first commit of some basics
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -100,3 +100,4 @@ Module.symvers
|
||||
Mkfile.old
|
||||
dkms.conf
|
||||
|
||||
build
|
||||
3
.vscode/settings.json
vendored
Normal file
3
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"cmake.ignoreCMakeListsMissing": true
|
||||
}
|
||||
53
TSE_Base/CMakeLists.txt
Normal file
53
TSE_Base/CMakeLists.txt
Normal file
@@ -0,0 +1,53 @@
|
||||
#cmake version
|
||||
cmake_minimum_required(VERSION 3.31)
|
||||
|
||||
#project name
|
||||
project(TSE_Base)
|
||||
|
||||
#cpp settings
|
||||
find_program(CLANG_C NAMES clang)
|
||||
find_program(CLANG_CXX NAMES clang++)
|
||||
|
||||
if(CLANG_C AND CLANG_CXX)
|
||||
message(STATUS "foung Clang, using as Compiler")
|
||||
set(CMAKE_C_COMPILER ${CLANG_C} CACHE STRING "C Compiler" FORCE)
|
||||
set(CMAKE_CXX_COMPILER ${CLANG_CXX} CACHE STRING "C++ Compiler" FORCE)
|
||||
else()
|
||||
message(STATUS "Clang not found, using Standard-Compiler")
|
||||
endif()
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
||||
|
||||
#project output settings
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/lib")
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG "${PROJECT_SOURCE_DIR}/lib/Debug")
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE "${PROJECT_SOURCE_DIR}/lib/Release")
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/lib")
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG "${PROJECT_SOURCE_DIR}/lib/Debug")
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE "${PROJECT_SOURCE_DIR}/lib/Release")
|
||||
|
||||
#source files
|
||||
file(GLOB CPP_SOURCE_TSE
|
||||
"${PROJECT_SOURCE_DIR}/src/*.cpp"
|
||||
"${PROJECT_SOURCE_DIR}/src/*/*.cpp"
|
||||
"${PROJECT_SOURCE_DIR}/src/*/*/*.cpp"
|
||||
"${PROJECT_SOURCE_DIR}/src/*/*/*/*.cpp"
|
||||
"${PROJECT_SOURCE_DIR}/src/*.c"
|
||||
"${PROJECT_SOURCE_DIR}/src/*/*.c"
|
||||
"${PROJECT_SOURCE_DIR}/src/*/*/*.c"
|
||||
"${PROJECT_SOURCE_DIR}/src/*/*/*/*.c"
|
||||
)
|
||||
|
||||
#includes
|
||||
include_directories(${PROJECT_SOURCE_DIR}/src)
|
||||
include_directories(${PROJECT_SOURCE_DIR}/include)
|
||||
|
||||
#project def
|
||||
if(Lib)
|
||||
add_library(TSE_Base SHARED ${CPP_SOURCE_TSE})
|
||||
else()
|
||||
add_library(TSE_Base STATIC ${CPP_SOURCE_TSE})
|
||||
endif()
|
||||
|
||||
#flags
|
||||
target_compile_options(TSE_Base PRIVATE -march=native)
|
||||
10664
TSE_Base/include/LuaBridge.h
Normal file
10664
TSE_Base/include/LuaBridge.h
Normal file
File diff suppressed because it is too large
Load Diff
82
TSE_Base/src/Debug.cpp
Normal file
82
TSE_Base/src/Debug.cpp
Normal file
@@ -0,0 +1,82 @@
|
||||
#include "Debug.hpp"
|
||||
|
||||
#include "PathHelper.hpp"
|
||||
|
||||
|
||||
std::ofstream TSE::Debug::logFile;
|
||||
const std::string fileName = "log.txt";
|
||||
const std::string fileNameOld = "lastlog.txt";
|
||||
|
||||
int luaPrintRedirect(lua_State* L)
|
||||
{
|
||||
int n = lua_gettop(L);
|
||||
|
||||
std::string out;
|
||||
out.reserve(256);
|
||||
|
||||
for (int i = 1; i <= n; ++i) {
|
||||
const char* s = lua_tostring(L, i);
|
||||
if (s)
|
||||
out += s;
|
||||
else
|
||||
out += "<non-string>";
|
||||
if (i < n)
|
||||
out += "\t";
|
||||
}
|
||||
|
||||
TSE_LOG(out);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void TSE::Debug::Init()
|
||||
{
|
||||
std::string path = "";
|
||||
std::string oldpath = "";
|
||||
GetAppDataPath(path);
|
||||
CombinePaths(oldpath, path, fileNameOld);
|
||||
CombinePaths(path, path, fileName);
|
||||
|
||||
if(FileExists(path))
|
||||
{
|
||||
if(FileExists(oldpath))
|
||||
{
|
||||
std::remove(oldpath.c_str());
|
||||
}
|
||||
std::rename(path.c_str(), oldpath.c_str());
|
||||
}
|
||||
|
||||
CreateFileWriting(logFile, path);
|
||||
|
||||
luabridge::getGlobalNamespace(TSE_LUA_STATE)
|
||||
.beginNamespace("debug")
|
||||
.addFunction("log", TSE::Debug::Log)
|
||||
.addFunction("warning", TSE::Debug::Warning)
|
||||
.addFunction("error", TSE::Debug::Error)
|
||||
.endNamespace();
|
||||
lua_pushcfunction(TSE_LUA_STATE, luaPrintRedirect);
|
||||
lua_setglobal(TSE_LUA_STATE, "print");
|
||||
}
|
||||
|
||||
void TSE::Debug::Log(string msg)
|
||||
{
|
||||
std::cout << msg << std::endl;
|
||||
logFile << msg << std::endl;
|
||||
}
|
||||
|
||||
void TSE::Debug::Error(string msg)
|
||||
{
|
||||
std::cerr << "[Error] " << msg << std::endl;
|
||||
logFile << "[Error] " << msg << std::endl;
|
||||
}
|
||||
|
||||
void TSE::Debug::Warning(string msg)
|
||||
{
|
||||
std::cout << "[Warning] " << msg << std::endl;
|
||||
logFile << "[Warning] " << msg << std::endl;
|
||||
}
|
||||
|
||||
void TSE::Debug::Close()
|
||||
{
|
||||
logFile.flush();
|
||||
logFile.close();
|
||||
}
|
||||
35
TSE_Base/src/Debug.hpp
Normal file
35
TSE_Base/src/Debug.hpp
Normal file
@@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
|
||||
#include "LuaStateHandler.hpp"
|
||||
#include "Types.hpp"
|
||||
|
||||
#define TSE_LOG(msg) TSE::Debug::Log(msg)
|
||||
#define TSE_ERROR(msg) TSE::Debug::Error(msg)
|
||||
#define TSE_WARNING(msg) TSE::Debug::Warning(msg)
|
||||
|
||||
namespace TSE
|
||||
{
|
||||
class Debug
|
||||
{
|
||||
public:
|
||||
/// @brief initializes the log file in app data or .local, and binds lua functions
|
||||
static void Init();
|
||||
/// @brief logs soumething to the stdout, and into the log file
|
||||
/// @param msg the message to be logged
|
||||
static void Log(string msg);
|
||||
/// @brief logs soumething to the stdout, and into the log file
|
||||
/// @param msg the message to be logged
|
||||
static void Error(string msg);
|
||||
/// @brief logs soumething to the stdout, and into the log file
|
||||
/// @param msg the message to be logged
|
||||
static void Warning(string msg);
|
||||
/// @brief closes the log file
|
||||
static void Close();
|
||||
|
||||
private:
|
||||
static std::ofstream logFile;
|
||||
};
|
||||
|
||||
} // namespace TSE
|
||||
|
||||
|
||||
42
TSE_Base/src/LuaStateHandler.cpp
Normal file
42
TSE_Base/src/LuaStateHandler.cpp
Normal file
@@ -0,0 +1,42 @@
|
||||
#include "LuaStateHandler.hpp"
|
||||
#include "version.h"
|
||||
#include "Debug.hpp"
|
||||
|
||||
void printVersionString()
|
||||
{
|
||||
TSE_LOG("TSE: " + TSE_VERSION_STRING);
|
||||
}
|
||||
|
||||
void TSE::LuaStateHandler::InitLuaState()
|
||||
{
|
||||
L = luaL_newstate();
|
||||
luaL_openlibs(L);
|
||||
|
||||
luabridge::getGlobalNamespace(TSE_LUA_STATE)
|
||||
.beginNamespace("engine")
|
||||
.addProperty("version", getVersionString)
|
||||
.addFunction("printVersion", printVersionString)
|
||||
.endNamespace();
|
||||
}
|
||||
|
||||
void TSE::LuaStateHandler::RunLuaString(string cmd)
|
||||
{
|
||||
int res = luaL_dostring(L, cmd.c_str());
|
||||
if (res != LUA_OK)
|
||||
{
|
||||
const char* err = lua_tostring(L, -1);
|
||||
TSE_ERROR(err ? err : "<unknown lua error>");
|
||||
lua_pop(L,1);
|
||||
}
|
||||
}
|
||||
|
||||
void TSE::LuaStateHandler::RunLuaScript(string path)
|
||||
{
|
||||
int res = luaL_dofile(L, path.c_str());
|
||||
if (res != LUA_OK)
|
||||
{
|
||||
const char* err = lua_tostring(L, -1);
|
||||
TSE_ERROR(err ? err : "<unknown lua error>");
|
||||
lua_pop(L,1);
|
||||
}
|
||||
}
|
||||
22
TSE_Base/src/LuaStateHandler.hpp
Normal file
22
TSE_Base/src/LuaStateHandler.hpp
Normal file
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include <lua5.4/lua.hpp>
|
||||
#include "LuaBridge.h"
|
||||
#include "Types.hpp"
|
||||
|
||||
#define TSE_LUA_STATE TSE::LuaStateHandler::L
|
||||
#define TSE_LUA_RUN_COMMAND(cmd) TSE::LuaStateHandler::RunLuaString(cmd)
|
||||
#define TSE_LUA_RUN_SCRIPT(path) TSE::LuaStateHandler::RunLuaScript(path)
|
||||
|
||||
namespace TSE
|
||||
{
|
||||
class LuaStateHandler
|
||||
{
|
||||
public:
|
||||
static inline lua_State* L;
|
||||
|
||||
static void InitLuaState();
|
||||
static void RunLuaString(string cmd);
|
||||
static void RunLuaScript(string path);
|
||||
};
|
||||
} // namespace TSE
|
||||
68
TSE_Base/src/PathHelper.cpp
Normal file
68
TSE_Base/src/PathHelper.cpp
Normal file
@@ -0,0 +1,68 @@
|
||||
#include "PathHelper.hpp"
|
||||
|
||||
#include <filesystem>
|
||||
#include <cstdlib>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#include <shlobj.h> // SHGetFolderPath
|
||||
#pragma comment(lib, "shell32.lib")
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <pwd.h>
|
||||
#endif
|
||||
|
||||
bool TSE::FileExists(const std::string &path)
|
||||
{
|
||||
return std::filesystem::exists(path);
|
||||
}
|
||||
|
||||
void TSE::OpenFileReading(std::ifstream &stream, const std::string &path)
|
||||
{
|
||||
stream.open(path, std::ios::in);
|
||||
}
|
||||
|
||||
void TSE::CreateFileWriting(std::ofstream &stream, const std::string &path)
|
||||
{
|
||||
stream.open(path, std::ios::out);
|
||||
}
|
||||
|
||||
void TSE::AppendFileWriting(std::ofstream &stream, const std::string &path)
|
||||
{
|
||||
stream.open(path, std::ios::app);
|
||||
}
|
||||
|
||||
void TSE::GetAppDataPath(std::string &path)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
char appDataPath[MAX_PATH];
|
||||
if (SUCCEEDED(SHGetFolderPathA(nullptr, CSIDL_APPDATA, nullptr, 0, appDataPath))) {
|
||||
path = std::string(appDataPath) + "\\TSE";
|
||||
} else {
|
||||
path = ".\\TSE"; // fallback
|
||||
}
|
||||
#else
|
||||
const char* homeDir = getenv("HOME");
|
||||
if (!homeDir) {
|
||||
struct passwd* pw = getpwuid(getuid());
|
||||
homeDir = pw->pw_dir;
|
||||
}
|
||||
path = std::string(homeDir) + "/.local/share/TSE";
|
||||
#endif
|
||||
if(!FileExists(path)){
|
||||
std::filesystem::create_directory(path);
|
||||
}
|
||||
}
|
||||
|
||||
void TSE::CombinePaths(std::string &res, const std::string &path1, const std::string &path2)
|
||||
{
|
||||
|
||||
#ifdef _WIN32
|
||||
//check for path parts containing forwardlasches
|
||||
res = path1 + "\\" + path2;
|
||||
#else
|
||||
//check for path parts containing backslasches
|
||||
res = path1 + "/" + path2;
|
||||
#endif
|
||||
}
|
||||
33
TSE_Base/src/PathHelper.hpp
Normal file
33
TSE_Base/src/PathHelper.hpp
Normal file
@@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include "Types.hpp"
|
||||
#include <fstream>
|
||||
|
||||
namespace TSE
|
||||
{
|
||||
/// @brief checks if a file exists at a path
|
||||
/// @param path the path to check
|
||||
/// @return file exists
|
||||
bool FileExists(const std::string& path);
|
||||
/// @brief opens a path for reading
|
||||
/// @param stream the stream to be assigned
|
||||
/// @param path the path to open
|
||||
void OpenFileReading(std::ifstream& stream, const std::string& path);
|
||||
/// @brief opens a path for writing
|
||||
/// @param stream the stream to be assigned
|
||||
/// @param path the path to open
|
||||
void CreateFileWriting(std::ofstream& stream, const std::string& path);
|
||||
/// @brief opens a path for appending
|
||||
/// @param stream the stream to be assigned
|
||||
/// @param path the path to open
|
||||
void AppendFileWriting(std::ofstream& stream, const std::string& path);
|
||||
|
||||
/// @brief gets the platform specific tmp folder in appdata or .local
|
||||
/// @param path the resulting path
|
||||
void GetAppDataPath(std::string& path);
|
||||
/// @brief combines two paths in a platform specific way
|
||||
/// @param res the resulting path
|
||||
/// @param path1 path part 1
|
||||
/// @param path2 path part 2
|
||||
void CombinePaths(std::string& res,const std::string& path1,const std::string& path2);
|
||||
} // namespace TSE
|
||||
17
TSE_Base/src/Types.hpp
Normal file
17
TSE_Base/src/Types.hpp
Normal file
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace TSE
|
||||
{
|
||||
typedef std::string string;
|
||||
|
||||
typedef char byte;
|
||||
typedef signed char sbyte;
|
||||
|
||||
typedef unsigned short ushort;
|
||||
typedef unsigned int uint;
|
||||
typedef unsigned long ulong;
|
||||
|
||||
|
||||
} // namespace TSE
|
||||
10
TSE_Base/src/version.h
Normal file
10
TSE_Base/src/version.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
|
||||
#define TSE_VERSION_MAJOR 0
|
||||
#define TSE_VERSION_MINOR 0
|
||||
#define TSE_VERSION_BUILD 1
|
||||
|
||||
#define TSE_VERSION_STRING std::to_string(TSE_VERSION_MAJOR) + "." + std::to_string(TSE_VERSION_MINOR) + "." + std::to_string(TSE_VERSION_BUILD)
|
||||
|
||||
std::string getVersionString() { return TSE_VERSION_STRING; }
|
||||
56
TSE_Core/CMakeLists.txt
Normal file
56
TSE_Core/CMakeLists.txt
Normal file
@@ -0,0 +1,56 @@
|
||||
#cmake version
|
||||
cmake_minimum_required(VERSION 3.31)
|
||||
|
||||
#project name
|
||||
project(TSE_Core)
|
||||
|
||||
#cpp settings
|
||||
find_program(CLANG_C NAMES clang)
|
||||
find_program(CLANG_CXX NAMES clang++)
|
||||
|
||||
if(CLANG_C AND CLANG_CXX)
|
||||
message(STATUS "foung Clang, using as Compiler")
|
||||
set(CMAKE_C_COMPILER ${CLANG_C} CACHE STRING "C Compiler" FORCE)
|
||||
set(CMAKE_CXX_COMPILER ${CLANG_CXX} CACHE STRING "C++ Compiler" FORCE)
|
||||
else()
|
||||
message(STATUS "Clang not found, using Standard-Compiler")
|
||||
endif()
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
||||
|
||||
#project output settings
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/lib")
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG "${PROJECT_SOURCE_DIR}/lib/Debug")
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE "${PROJECT_SOURCE_DIR}/lib/Release")
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/lib")
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG "${PROJECT_SOURCE_DIR}/lib/Debug")
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE "${PROJECT_SOURCE_DIR}/lib/Release")
|
||||
|
||||
#source files
|
||||
file(GLOB CPP_SOURCE_TSE
|
||||
"${PROJECT_SOURCE_DIR}/src/*.cpp"
|
||||
"${PROJECT_SOURCE_DIR}/src/*/*.cpp"
|
||||
"${PROJECT_SOURCE_DIR}/src/*/*/*.cpp"
|
||||
"${PROJECT_SOURCE_DIR}/src/*/*/*/*.cpp"
|
||||
"${PROJECT_SOURCE_DIR}/src/*.c"
|
||||
"${PROJECT_SOURCE_DIR}/src/*/*.c"
|
||||
"${PROJECT_SOURCE_DIR}/src/*/*/*.c"
|
||||
"${PROJECT_SOURCE_DIR}/src/*/*/*/*.c"
|
||||
)
|
||||
|
||||
#includes
|
||||
include_directories(${PROJECT_SOURCE_DIR}/src)
|
||||
include_directories(${PROJECT_SOURCE_DIR}/../TSE_Math/src)
|
||||
include_directories(${PROJECT_SOURCE_DIR}/../TSE_Base/src)
|
||||
include_directories(${PROJECT_SOURCE_DIR}/../TSE_Base/include)
|
||||
|
||||
#project def
|
||||
if(Lib)
|
||||
add_library(TSE_Core SHARED ${CPP_SOURCE_TSE})
|
||||
else()
|
||||
add_library(TSE_Core STATIC ${CPP_SOURCE_TSE})
|
||||
endif()
|
||||
|
||||
#flags
|
||||
target_compile_options(TSE_Core PRIVATE -march=native)
|
||||
|
||||
13
TSE_Core/src/enums/WindowType.hpp
Normal file
13
TSE_Core/src/enums/WindowType.hpp
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
namespace TSE
|
||||
{
|
||||
enum WindowType
|
||||
{
|
||||
Unnknown = 0,
|
||||
Windowed = 1,
|
||||
Fullscreen = 2,
|
||||
FullscreenWindowed = 3,
|
||||
Maximized = 4,
|
||||
};
|
||||
} // namespace TSE
|
||||
16
TSE_Core/src/interfaces/IRenderTarget.hpp
Normal file
16
TSE_Core/src/interfaces/IRenderTarget.hpp
Normal file
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "IResizable.hpp"
|
||||
|
||||
namespace TSE
|
||||
{
|
||||
class IRenderTarget : public IResizable
|
||||
{
|
||||
public:
|
||||
int UnitScaler = 32;
|
||||
|
||||
virtual void Update();
|
||||
virtual void Bind();
|
||||
virtual void Unbind();
|
||||
};
|
||||
} // namespace TSE
|
||||
29
TSE_Core/src/interfaces/IRenderingBackend.hpp
Normal file
29
TSE_Core/src/interfaces/IRenderingBackend.hpp
Normal file
@@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#include "Color.hpp"
|
||||
|
||||
namespace TSE
|
||||
{
|
||||
class IWindow;
|
||||
|
||||
class IRenderingBackend
|
||||
{
|
||||
protected:
|
||||
Color backgroundColor;
|
||||
bool vsync;
|
||||
int samples = 0;
|
||||
bool useseImGui = false;
|
||||
|
||||
public:
|
||||
IWindow* window = nullptr;
|
||||
|
||||
virtual void InitPreWindow() = 0;
|
||||
virtual bool InitPostWindow() = 0;
|
||||
|
||||
virtual void onResize(int width, int height) = 0;
|
||||
virtual void onUpdate() const = 0;
|
||||
virtual void onClear() const = 0;
|
||||
virtual void onClearDepthBuffer() const = 0;
|
||||
|
||||
};
|
||||
} // namespace TSE
|
||||
25
TSE_Core/src/interfaces/IResizable.cpp
Normal file
25
TSE_Core/src/interfaces/IResizable.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
#include "IResizable.hpp"
|
||||
|
||||
void TSE::IResizable::AddResizeNotifiable(IResizeNotifiable *obj)
|
||||
{
|
||||
std::list<IResizeNotifiable*>::iterator it;
|
||||
for (it = objectsToResize.begin(); it != objectsToResize.end(); ++it)
|
||||
{
|
||||
if((*it) == obj){
|
||||
return; //return if already in list
|
||||
}
|
||||
}
|
||||
objectsToResize.push_back(obj);
|
||||
}
|
||||
|
||||
void TSE::IResizable::RemoveResizeNotifiable(IResizeNotifiable *obj)
|
||||
{
|
||||
std::list<IResizeNotifiable*>::iterator it;
|
||||
for (it = objectsToResize.begin(); it != objectsToResize.end(); ++it)
|
||||
{
|
||||
if((*it) == obj){
|
||||
objectsToResize.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
19
TSE_Core/src/interfaces/IResizable.hpp
Normal file
19
TSE_Core/src/interfaces/IResizable.hpp
Normal file
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <list>
|
||||
#include "IResizeNotifiable.hpp"
|
||||
|
||||
namespace TSE
|
||||
{
|
||||
class IResizable
|
||||
{
|
||||
protected:
|
||||
float width;
|
||||
float height;
|
||||
std::list<IResizeNotifiable*> objectsToResize;
|
||||
|
||||
public:
|
||||
void AddResizeNotifiable(IResizeNotifiable* obj);
|
||||
void RemoveResizeNotifiable(IResizeNotifiable* obj);
|
||||
};
|
||||
} // namespace TSE
|
||||
18
TSE_Core/src/interfaces/IResizeNotifiable.hpp
Normal file
18
TSE_Core/src/interfaces/IResizeNotifiable.hpp
Normal file
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
namespace TSE
|
||||
{
|
||||
class IResizable;
|
||||
|
||||
class IResizeNotifiable
|
||||
{
|
||||
public:
|
||||
/// @brief gets called, when a Resizable gets resized as an event.
|
||||
/// @param width the new width
|
||||
/// @param height the new height
|
||||
/// @param resizable the resizable that got changed
|
||||
virtual void OnResize(float width, float height, IResizable* resizable);
|
||||
virtual ~IResizeNotifiable() = default;
|
||||
};
|
||||
} // namespace TSE
|
||||
16
TSE_Core/src/interfaces/IWindow.cpp
Normal file
16
TSE_Core/src/interfaces/IWindow.cpp
Normal file
@@ -0,0 +1,16 @@
|
||||
#include "IWindow.hpp"
|
||||
#include "Debug.hpp"
|
||||
#include "LuaStateHandler.hpp"
|
||||
|
||||
TSE::IWindow* TSE::IWindow::lastWindow = nullptr;
|
||||
|
||||
bool TSE::IWindow::BaseInit() const
|
||||
{
|
||||
LuaStateHandler::InitLuaState();
|
||||
Debug::Init();
|
||||
}
|
||||
|
||||
TSE::IWindow::~IWindow()
|
||||
{
|
||||
Debug::Close();
|
||||
}
|
||||
25
TSE_Core/src/interfaces/IWindow.hpp
Normal file
25
TSE_Core/src/interfaces/IWindow.hpp
Normal file
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include "IRenderTarget.hpp"
|
||||
#include "Types.hpp"
|
||||
|
||||
namespace TSE
|
||||
{
|
||||
class IWindow : public IRenderTarget
|
||||
{
|
||||
public:
|
||||
static IWindow* lastWindow;
|
||||
string title;
|
||||
|
||||
protected:
|
||||
virtual bool Init() = 0;
|
||||
public:
|
||||
virtual void Clear() const = 0;
|
||||
virtual void Update() const = 0;
|
||||
virtual void ClearDepthBuffer() const = 0;
|
||||
virtual bool ShouldClose() const = 0;
|
||||
|
||||
bool BaseInit() const;
|
||||
~IWindow();
|
||||
};
|
||||
} // namespace TSE
|
||||
55
TSE_Math/CMakeLists.txt
Normal file
55
TSE_Math/CMakeLists.txt
Normal file
@@ -0,0 +1,55 @@
|
||||
#cmake version
|
||||
cmake_minimum_required(VERSION 3.31)
|
||||
|
||||
#project name
|
||||
project(TSE_Math)
|
||||
|
||||
#cpp settings
|
||||
find_program(CLANG_C NAMES clang)
|
||||
find_program(CLANG_CXX NAMES clang++)
|
||||
|
||||
if(CLANG_C AND CLANG_CXX)
|
||||
message(STATUS "foung Clang, using as Compiler")
|
||||
set(CMAKE_C_COMPILER ${CLANG_C} CACHE STRING "C Compiler" FORCE)
|
||||
set(CMAKE_CXX_COMPILER ${CLANG_CXX} CACHE STRING "C++ Compiler" FORCE)
|
||||
else()
|
||||
message(STATUS "Clang not found, using Standard-Compiler")
|
||||
endif()
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
||||
|
||||
#project output settings
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/lib")
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG "${PROJECT_SOURCE_DIR}/lib/Debug")
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE "${PROJECT_SOURCE_DIR}/lib/Release")
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/lib")
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG "${PROJECT_SOURCE_DIR}/lib/Debug")
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE "${PROJECT_SOURCE_DIR}/lib/Release")
|
||||
|
||||
#source files
|
||||
file(GLOB CPP_SOURCE_TSE
|
||||
"${PROJECT_SOURCE_DIR}/src/*.cpp"
|
||||
"${PROJECT_SOURCE_DIR}/src/*/*.cpp"
|
||||
"${PROJECT_SOURCE_DIR}/src/*/*/*.cpp"
|
||||
"${PROJECT_SOURCE_DIR}/src/*/*/*/*.cpp"
|
||||
"${PROJECT_SOURCE_DIR}/src/*.c"
|
||||
"${PROJECT_SOURCE_DIR}/src/*/*.c"
|
||||
"${PROJECT_SOURCE_DIR}/src/*/*/*.c"
|
||||
"${PROJECT_SOURCE_DIR}/src/*/*/*/*.c"
|
||||
)
|
||||
|
||||
#includes
|
||||
include_directories(${PROJECT_SOURCE_DIR}/src)
|
||||
include_directories(${PROJECT_SOURCE_DIR}/../TSE_Base/src)
|
||||
|
||||
#project def
|
||||
#add_library(TSE_Math STATIC ${CPP_SOURCE_TSE})
|
||||
if(Lib)
|
||||
add_library(TSE_Math SHARED ${CPP_SOURCE_TSE})
|
||||
else()
|
||||
add_library(TSE_Math STATIC ${CPP_SOURCE_TSE})
|
||||
endif()
|
||||
|
||||
#flags
|
||||
target_compile_options(TSE_Math PRIVATE -march=native)
|
||||
|
||||
178
TSE_Math/src/Color.cpp
Normal file
178
TSE_Math/src/Color.cpp
Normal file
@@ -0,0 +1,178 @@
|
||||
#include "Color.hpp"
|
||||
#include "Vector4.hpp"
|
||||
#include <cmath>
|
||||
|
||||
TSE::Color const TSE::Color::red = TSE::Color(1.0f,0.0f,0.0f);
|
||||
TSE::Color const TSE::Color::blue = TSE::Color(0.0f,1.0f,0.0f);
|
||||
TSE::Color const TSE::Color::green = TSE::Color(0.0f,0.0f,1.0f);
|
||||
TSE::Color const TSE::Color::white = TSE::Color(1.0f,1.0f,1.0f);
|
||||
TSE::Color const TSE::Color::black = TSE::Color(0.0f,0.0f,0.0f);
|
||||
TSE::Color const TSE::Color::gray = TSE::Color(0.5f,0.5f,0.5f);
|
||||
TSE::Color const TSE::Color::darkGray = TSE::Color(0.2f,0.2f,0.2f);
|
||||
TSE::Color const TSE::Color::yellow = TSE::Color(1.0f,1.0f,0.0f);
|
||||
TSE::Color const TSE::Color::orange = TSE::Color(1.0f,0.5f,0.0f);
|
||||
TSE::Color const TSE::Color::aqua = TSE::Color(0.0f,1.0f,1.0f);
|
||||
|
||||
TSE::Color::Color() { }
|
||||
|
||||
TSE::Color::Color(float _r, float _g, float _b)
|
||||
{
|
||||
r = _r;
|
||||
g = _g;
|
||||
b = _b;
|
||||
}
|
||||
|
||||
TSE::Color::Color(float _r, float _g, float _b, float _a)
|
||||
{
|
||||
r = _r;
|
||||
g = _g;
|
||||
b = _b;
|
||||
a = _a;
|
||||
}
|
||||
|
||||
TSE::Color::Color(byte _r, byte _g, byte _b)
|
||||
{
|
||||
r = _r / 255.0f;
|
||||
g = _g / 255.0f;
|
||||
b = _b / 255.0f;
|
||||
}
|
||||
|
||||
TSE::Color::Color(byte _r, byte _g, byte _b, byte _a)
|
||||
{
|
||||
r = _r / 255.0f;
|
||||
g = _g / 255.0f;
|
||||
b = _b / 255.0f;
|
||||
a = _a / 255.0f;
|
||||
}
|
||||
|
||||
TSE::Color::Color(const Color &other)
|
||||
{
|
||||
r = other.r;
|
||||
g = other.g;
|
||||
b = other.b;
|
||||
a = other.a;
|
||||
}
|
||||
|
||||
TSE::Color::Color(const Vector4 &other)
|
||||
{
|
||||
r = other.x;
|
||||
g = other.y;
|
||||
b = other.z;
|
||||
a = other.w;
|
||||
}
|
||||
|
||||
bool TSE::Color::IsValid() const
|
||||
{
|
||||
return (!std::isnan(r) && r >= 0 && r <= 1) && (!std::isnan(g) && g >= 0 && g <= 1) && (!std::isnan(b) && b >= 0 && b <= 1) && (!std::isnan(a) && a >= 0 && a <= 1);
|
||||
}
|
||||
|
||||
TSE::byte TSE::Color::R() const
|
||||
{
|
||||
return r * 255;
|
||||
}
|
||||
|
||||
TSE::byte TSE::Color::G() const
|
||||
{
|
||||
return g * 255;
|
||||
}
|
||||
|
||||
TSE::byte TSE::Color::B() const
|
||||
{
|
||||
return b * 255;
|
||||
}
|
||||
|
||||
TSE::byte TSE::Color::A() const
|
||||
{
|
||||
return a * 255;
|
||||
}
|
||||
|
||||
TSE::string TSE::Color::ToString() const
|
||||
{
|
||||
return "(" + std::to_string(r) + "|" + std::to_string(g) + "|" + std::to_string(b) + "|" + std::to_string(a) + ")";
|
||||
}
|
||||
|
||||
TSE::Vector4 TSE::Color::ToVector4() const
|
||||
{
|
||||
return Vector4(r,g,b,a);
|
||||
}
|
||||
|
||||
TSE::Color TSE::Color::Lerp(const Color &a, const Color &b, const float t)
|
||||
{
|
||||
return a + (b - a) * t;
|
||||
}
|
||||
|
||||
TSE::Color TSE::Color::operator+(const Color &other) const
|
||||
{
|
||||
return Vector4(r + other.r, g + other.g, b + other.b, a + other.a);
|
||||
}
|
||||
|
||||
TSE::Color TSE::Color::operator+=(const Color &other)
|
||||
{
|
||||
*this = *this + other;
|
||||
return *this;
|
||||
}
|
||||
|
||||
TSE::Color TSE::Color::operator-(const Color &other) const
|
||||
{
|
||||
return Vector4(r - other.r, g - other.g, b - other.b, a - other.a);
|
||||
}
|
||||
|
||||
TSE::Color TSE::Color::operator-=(const Color &other)
|
||||
{
|
||||
*this = *this - other;
|
||||
return *this;
|
||||
}
|
||||
|
||||
TSE::Color TSE::Color::operator*(const Color &other) const
|
||||
{
|
||||
return Vector4(r * other.r, g * other.g, b * other.b, a * other.a);
|
||||
}
|
||||
|
||||
TSE::Color TSE::Color::operator*=(const Color &other)
|
||||
{
|
||||
*this = *this * other;
|
||||
return *this;
|
||||
}
|
||||
|
||||
TSE::Color TSE::Color::operator/(const Color &other) const
|
||||
{
|
||||
return Vector4(r / other.r, g / other.g, b / other.b, a / other.a);
|
||||
}
|
||||
|
||||
TSE::Color TSE::Color::operator/=(const Color &other)
|
||||
{
|
||||
*this = *this / other;
|
||||
return *this;
|
||||
}
|
||||
|
||||
TSE::Color TSE::Color::operator*(const float other) const
|
||||
{
|
||||
return Vector4(r * other, g * other, b * other, a * other);
|
||||
}
|
||||
|
||||
TSE::Color TSE::Color::operator*=(const float other)
|
||||
{
|
||||
*this = *this * other;
|
||||
return *this;
|
||||
}
|
||||
|
||||
TSE::Color TSE::Color::operator/(const float other) const
|
||||
{
|
||||
return Vector4(r / other, g / other, b / other, a / other);
|
||||
}
|
||||
|
||||
TSE::Color TSE::Color::operator/=(const float other)
|
||||
{
|
||||
*this = *this / other;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool TSE::Color::operator==(const Color &other) const
|
||||
{
|
||||
return r == other.r && g == other.g && b == other.b && a == other.a;
|
||||
}
|
||||
|
||||
bool TSE::Color::operator!=(const Color &other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
113
TSE_Math/src/Color.hpp
Normal file
113
TSE_Math/src/Color.hpp
Normal file
@@ -0,0 +1,113 @@
|
||||
#pragma once
|
||||
|
||||
#include "Types.hpp"
|
||||
|
||||
namespace TSE
|
||||
{
|
||||
class Vector4;
|
||||
|
||||
/// @brief the color class for the engine
|
||||
class Color
|
||||
{
|
||||
public:
|
||||
#pragma region members
|
||||
float r = 0, g = 0, b = 0, a = 1;
|
||||
#pragma endregion members
|
||||
|
||||
#pragma region consts
|
||||
static const Color red;
|
||||
static const Color green;
|
||||
static const Color blue;
|
||||
static const Color white;
|
||||
static const Color black;
|
||||
static const Color gray;
|
||||
static const Color darkGray;
|
||||
static const Color yellow;
|
||||
static const Color orange;
|
||||
static const Color aqua;
|
||||
#pragma endregion consts
|
||||
|
||||
#pragma region ctor
|
||||
/// @brief empty constructor. Gives you a black color with a full alpha
|
||||
Color();
|
||||
/// @brief construct a color with float values ranging from 0 - 1
|
||||
/// @param _r red component
|
||||
/// @param _g green component
|
||||
/// @param _b blue component
|
||||
Color(float _r, float _g, float _b);
|
||||
/// @brief construct a color with float values ranging from 0 - 1
|
||||
/// @param _r red component
|
||||
/// @param _g green component
|
||||
/// @param _b blue component
|
||||
/// @param _a alpha component
|
||||
Color(float _r, float _g, float _b, float _a);
|
||||
/// @brief construct a color with byte values ranging from 0 - 255
|
||||
/// @param _r red component
|
||||
/// @param _g green component
|
||||
/// @param _b blue component
|
||||
Color(byte _r, byte _g, byte _b);
|
||||
/// @brief construct a color with byte values ranging from 0 - 255
|
||||
/// @param _r red component
|
||||
/// @param _g green component
|
||||
/// @param _b blue component
|
||||
/// @param _a alpha component
|
||||
Color(byte _r, byte _g, byte _b, byte _a);
|
||||
/// @brief copy constructor. It copies the values from the input color
|
||||
/// @param other input color
|
||||
Color(const Color& other);
|
||||
/// @brief convert constructor. It converts the values from the input vector4, where x -> r, y -> g, z -> b, w -> a
|
||||
/// @param other input vector4
|
||||
Color(const Vector4& other);
|
||||
#pragma endregion ctor
|
||||
|
||||
#pragma region methods
|
||||
/// @brief checks if the individual color chanels have valid values
|
||||
/// @return are the values valid
|
||||
bool IsValid() const;
|
||||
/// @brief gives you the red component as a byte
|
||||
/// @return the red component
|
||||
byte R() const;
|
||||
/// @brief gives you the green component as a byte
|
||||
/// @return the green component
|
||||
byte G() const;
|
||||
/// @brief gives you the blue component as a byte
|
||||
/// @return the blue component
|
||||
byte B() const;
|
||||
/// @brief gives you the alpha component as a byte
|
||||
/// @return the alpha component
|
||||
byte A() const;
|
||||
/// @brief gives you the color as a string representation. mostly for debugging
|
||||
/// @return the color in a format like (r|g|b|a)
|
||||
string ToString() const;
|
||||
/// @brief creates a Vector4 with the same values as the color, where x -> r, y -> g, z -> b, w -> a
|
||||
/// @return the color as a Vector4
|
||||
Vector4 ToVector4() const;
|
||||
|
||||
#pragma region static
|
||||
/// @brief Linearlie interpolates between two colors using t
|
||||
/// @param a Color1
|
||||
/// @param b Color2
|
||||
/// @param t the value that defines how much it schould be Color1 (0) or Color2 (1)
|
||||
/// @return the lerped color
|
||||
static Color Lerp(const Color& a, const Color& b, const float t);
|
||||
#pragma endregion static
|
||||
|
||||
#pragma region operators
|
||||
Color operator+(const Color& other) const;
|
||||
Color operator+=(const Color& other);
|
||||
Color operator-(const Color& other) const;
|
||||
Color operator-=(const Color& other);
|
||||
Color operator*(const Color& other) const;
|
||||
Color operator*=(const Color& other);
|
||||
Color operator/(const Color& other) const;
|
||||
Color operator/=(const Color& other);
|
||||
Color operator*(const float other) const;
|
||||
Color operator*=(const float other);
|
||||
Color operator/(const float other) const;
|
||||
Color operator/=(const float other);
|
||||
bool operator==(const Color& other) const;
|
||||
bool operator!=(const Color& other) const;
|
||||
#pragma endregion operators
|
||||
#pragma endregion methods
|
||||
};
|
||||
} // namespace TSE
|
||||
27
TSE_Math/src/MathF.hpp
Normal file
27
TSE_Math/src/MathF.hpp
Normal file
@@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
|
||||
#include "Types.hpp"
|
||||
|
||||
namespace TSE
|
||||
{
|
||||
|
||||
/// @brief definition of PI for the engine
|
||||
constexpr float TSE_PI = 3.14159265358979323846f;
|
||||
|
||||
/// @brief the epsilon used as min float value for comparisons in the engine
|
||||
constexpr float TSE_EPSILON = 1e-6f;
|
||||
|
||||
/// @brief a simple degrees to radiant conversion function
|
||||
/// @param deg the degrees value
|
||||
/// @return the radiant value
|
||||
inline float Deg2Rad(const float& deg) {
|
||||
return deg * (TSE_PI / 180.0f);
|
||||
}
|
||||
|
||||
/// @brief a simple radiant to degrees conversion function
|
||||
/// @param rad the radiant value
|
||||
/// @return the degrees value
|
||||
inline float Rad2Deg( const float& rad) {
|
||||
return rad * (180.0f / TSE_PI);
|
||||
}
|
||||
} // namespace TSE
|
||||
428
TSE_Math/src/Matrix4x4.cpp
Normal file
428
TSE_Math/src/Matrix4x4.cpp
Normal file
@@ -0,0 +1,428 @@
|
||||
#include "Matrix4x4.hpp"
|
||||
#include "MathF.hpp"
|
||||
#include <cstring>
|
||||
#include <cmath>
|
||||
|
||||
#ifdef __unix__
|
||||
#include <immintrin.h>
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#if defined(__AVX2__)
|
||||
#define SIMD_HAS_FMA 1
|
||||
#endif
|
||||
#elif defined(__FMA__)
|
||||
#define SIMD_HAS_FMA 1
|
||||
#endif
|
||||
|
||||
#if defined(__SSE4_1__) || (defined(_MSC_VER) && defined(__AVX2__))
|
||||
#define SIMD_HAS_DPPS 1
|
||||
#endif
|
||||
|
||||
TSE::Matrix4x4::Matrix4x4()
|
||||
{
|
||||
std::memset(m, 0, sizeof(m));
|
||||
}
|
||||
|
||||
TSE::Matrix4x4::Matrix4x4(float d)
|
||||
{
|
||||
std::memset(m, 0, sizeof(m));
|
||||
for (int i = 0; i < 4; ++i)
|
||||
m[i][i] = d;
|
||||
}
|
||||
|
||||
TSE::Matrix4x4::Matrix4x4(const Matrix4x4 &other)
|
||||
{
|
||||
std::memcpy(m, other.m, sizeof(m));
|
||||
}
|
||||
|
||||
bool TSE::Matrix4x4::IsIdentityMatrix() const
|
||||
{
|
||||
Matrix4x4 id = Identity();
|
||||
return std::memcmp(m, id.m, sizeof(m)) == 0;
|
||||
}
|
||||
|
||||
bool TSE::Matrix4x4::IsValid() const
|
||||
{
|
||||
bool valid = true;
|
||||
for (byte x = 0; x < 4; x++)
|
||||
{
|
||||
for (byte y = 0; y < 4; y++)
|
||||
{
|
||||
valid &= !std::isnan(m[x][y]);
|
||||
}
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
|
||||
void TSE::Matrix4x4::Invert()
|
||||
{
|
||||
const float det = Determinant();
|
||||
if(std::abs(det) < TSE_EPSILON)
|
||||
{
|
||||
*this = Matrix4x4::Identity();
|
||||
return;
|
||||
}
|
||||
|
||||
Matrix4x4 conj = Conjucate();
|
||||
float invDet = 1.0f / det;
|
||||
|
||||
*this = conj * invDet;
|
||||
return;
|
||||
}
|
||||
|
||||
float det3(float a00, float a01, float a02, float a10, float a11, float a12, float a20, float a21, float a22)
|
||||
{
|
||||
return a00 * (a11 * a22 - a12 * a21)
|
||||
- a01 * (a10 * a22 - a12 * a20)
|
||||
+ a02 * (a10 * a21 - a11 * a20);
|
||||
}
|
||||
|
||||
float minor3(const TSE::Matrix4x4& M, int i, int j)
|
||||
{
|
||||
int ri[3], ci[3];
|
||||
for (int r = 0, rr = 0; r < 4; ++r) if (r != i) ri[rr++] = r;
|
||||
for (int c = 0, cc = 0; c < 4; ++c) if (c != j) ci[cc++] = c;
|
||||
|
||||
return det3(
|
||||
M.m[ri[0]][ci[0]], M.m[ri[0]][ci[1]], M.m[ri[0]][ci[2]],
|
||||
M.m[ri[1]][ci[0]], M.m[ri[1]][ci[1]], M.m[ri[1]][ci[2]],
|
||||
M.m[ri[2]][ci[0]], M.m[ri[2]][ci[1]], M.m[ri[2]][ci[2]]
|
||||
);
|
||||
}
|
||||
|
||||
float cofactorSign(TSE::byte x, TSE::byte y)
|
||||
{
|
||||
return ((x + y) & 1) ? -1.0f : 1.0f;
|
||||
}
|
||||
|
||||
TSE::Matrix4x4 TSE::Matrix4x4::Conjucate() const
|
||||
{
|
||||
Matrix4x4 conj;
|
||||
|
||||
for (byte x = 0; x < 4; x++)
|
||||
{
|
||||
for (byte y = 0; y < 4; y++)
|
||||
{
|
||||
conj.m[x][y] = cofactorSign(x,y) * minor3(*this, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
return conj;
|
||||
}
|
||||
|
||||
float TSE::Matrix4x4::Determinant() const
|
||||
{
|
||||
const float c00 = cofactorSign(0,0) * minor3(*this, 0, 0);
|
||||
const float c01 = cofactorSign(0,1) * minor3(*this, 0, 1);
|
||||
const float c02 = cofactorSign(0,2) * minor3(*this, 0, 2);
|
||||
const float c03 = cofactorSign(0,3) * minor3(*this, 0, 3);
|
||||
|
||||
return m[0][0] * c00 + m[0][1] * c01 + m[0][2] * c02 + m[0][3] * c03;
|
||||
}
|
||||
|
||||
bool TSE::Matrix4x4::IsAffine() const
|
||||
{
|
||||
return std::abs(m[3][0]) < TSE_EPSILON &&
|
||||
std::abs(m[3][1]) < TSE_EPSILON &&
|
||||
std::abs(m[3][2]) < TSE_EPSILON &&
|
||||
std::abs(m[3][3] - 1.0f) < TSE_EPSILON;
|
||||
}
|
||||
|
||||
void TSE::Matrix4x4::InvertAffine()
|
||||
{
|
||||
const float a00 = m[0][0], a01 = m[0][1], a02 = m[0][2];
|
||||
const float a10 = m[1][0], a11 = m[1][1], a12 = m[1][2];
|
||||
const float a20 = m[2][0], a21 = m[2][1], a22 = m[2][2];
|
||||
|
||||
const float tx = m[0][3], ty = m[1][3], tz = m[2][3];
|
||||
|
||||
const float det =
|
||||
a00*(a11*a22 - a12*a21) -
|
||||
a01*(a10*a22 - a12*a20) +
|
||||
a02*(a10*a21 - a11*a20);
|
||||
|
||||
if (std::abs(det) < TSE_EPSILON) {
|
||||
*this = Matrix4x4::Identity();
|
||||
return;
|
||||
}
|
||||
|
||||
const float invDet = 1.0f / det;
|
||||
|
||||
m[0][0] = (a11*a22 - a12*a21) * invDet;
|
||||
m[0][1] = -(a01*a22 - a02*a21) * invDet;
|
||||
m[0][2] = (a01*a12 - a02*a11) * invDet;
|
||||
|
||||
m[1][0] = -(a10*a22 - a12*a20) * invDet;
|
||||
m[1][1] = (a00*a22 - a02*a20) * invDet;
|
||||
m[1][2] = -(a00*a12 - a02*a10) * invDet;
|
||||
|
||||
m[2][0] = (a10*a21 - a11*a20) * invDet;
|
||||
m[2][1] = -(a00*a21 - a01*a20) * invDet;
|
||||
m[2][2] = (a00*a11 - a01*a10) * invDet;
|
||||
|
||||
m[0][3] = -(m[0][0]*tx + m[0][1]*ty + m[0][2]*tz);
|
||||
m[1][3] = -(m[1][0]*tx + m[1][1]*ty + m[1][2]*tz);
|
||||
m[2][3] = -(m[2][0]*tx + m[2][1]*ty + m[2][2]*tz);
|
||||
|
||||
m[3][0] = 0.0f;
|
||||
m[3][1] = 0.0f;
|
||||
m[3][2] = 0.0f;
|
||||
m[3][3] = 1.0f;
|
||||
}
|
||||
|
||||
const float *TSE::Matrix4x4::ToArrayRowMajor() const
|
||||
{
|
||||
return &m[0][0];
|
||||
}
|
||||
|
||||
void TSE::Matrix4x4::ToArrayColumnMajor(float out[16]) const
|
||||
{
|
||||
for (byte row = 0; row < 4; ++row)
|
||||
for (byte col = 0; col < 4; ++col)
|
||||
out[col * 4 + row] = m[row][col];
|
||||
}
|
||||
|
||||
TSE::Matrix4x4 TSE::Matrix4x4::Identity()
|
||||
{
|
||||
return Matrix4x4(1.0f);
|
||||
}
|
||||
|
||||
TSE::Matrix4x4 TSE::Matrix4x4::Orthographic(float left, float right, float bottom, float top, float near, float far)
|
||||
{
|
||||
Matrix4x4 result = Matrix4x4(1.0f);
|
||||
|
||||
result.m[0][0] = 2.0f / (right - left);
|
||||
result.m[1][1] = 2.0f / (top - bottom);
|
||||
result.m[2][2] = -2.0f / (far - near);
|
||||
|
||||
result.m[0][3] = (left + right) / (left - right);
|
||||
result.m[1][3] = (bottom + top) / (bottom - top);
|
||||
result.m[2][3] = -(near + far) / (near - far);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
TSE::Matrix4x4 TSE::Matrix4x4::Perspective(float fov, float aspectRatio, float near, float far)
|
||||
{
|
||||
Matrix4x4 result = Matrix4x4(1.0f);
|
||||
|
||||
float q = 1 / tan(Deg2Rad(0.5f * fov));
|
||||
float a = q / aspectRatio;
|
||||
|
||||
float b = (near + far) / (near - far);
|
||||
float c = (2 * near * far) / (near - far);
|
||||
|
||||
result.m[0][0] = a;
|
||||
result.m[1][1] = q;
|
||||
result.m[2][2] = b;
|
||||
result.m[3][2] = -1;
|
||||
result.m[2][3] = c;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
TSE::Matrix4x4 TSE::Matrix4x4::ToTranslationMatrix(const Vector3 &pos)
|
||||
{
|
||||
Matrix4x4 result = Identity();
|
||||
result.m[0][3] = pos.x;
|
||||
result.m[1][3] = pos.y;
|
||||
result.m[2][3] = pos.z;
|
||||
return result;
|
||||
}
|
||||
|
||||
TSE::Matrix4x4 TSE::Matrix4x4::ToRotationMatrix(const Quaternion &rot)
|
||||
{
|
||||
Matrix4x4 result = Identity();
|
||||
float xx = rot.x * rot.x;
|
||||
float yy = rot.y * rot.y;
|
||||
float zz = rot.z * rot.z;
|
||||
float xy = rot.x * rot.y;
|
||||
float xz = rot.x * rot.z;
|
||||
float yz = rot.y * rot.z;
|
||||
float wx = rot.w * rot.x;
|
||||
float wy = rot.w * rot.y;
|
||||
float wz = rot.w * rot.z;
|
||||
|
||||
result.m[0][0] = 1.0f - 2.0f * (yy + zz);
|
||||
result.m[0][1] = 2.0f * (xy - wz);
|
||||
result.m[0][2] = 2.0f * (xz + wy);
|
||||
|
||||
result.m[1][0] = 2.0f * (xy + wz);
|
||||
result.m[1][1] = 1.0f - 2.0f * (xx + zz);
|
||||
result.m[1][2] = 2.0f * (yz - wx);
|
||||
|
||||
result.m[2][0] = 2.0f * (xz - wy);
|
||||
result.m[2][1] = 2.0f * (yz + wx);
|
||||
result.m[2][2] = 1.0f - 2.0f * (xx + yy);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
TSE::Matrix4x4 TSE::Matrix4x4::ToRotationMatrixFromZAxisOnly(float angle)
|
||||
{
|
||||
Matrix4x4 result = Identity();
|
||||
float c = std::cos(angle);
|
||||
float s = std::sin(angle);
|
||||
result.m[0][0] = c;
|
||||
result.m[0][1] = -s;
|
||||
result.m[1][0] = s;
|
||||
result.m[1][1] = c;
|
||||
return result;
|
||||
}
|
||||
|
||||
TSE::Matrix4x4 TSE::Matrix4x4::ToScaleMatrix(const Vector3 &scale)
|
||||
{
|
||||
Matrix4x4 result = Identity();
|
||||
result.m[0][0] = scale.x;
|
||||
result.m[1][1] = scale.y;
|
||||
result.m[2][2] = scale.z;
|
||||
return result;
|
||||
}
|
||||
|
||||
TSE::Matrix4x4 TSE::Matrix4x4::Invert(const Matrix4x4 &mat)
|
||||
{
|
||||
Matrix4x4 invers (mat);
|
||||
|
||||
if(invers.IsAffine())
|
||||
{
|
||||
invers.InvertAffine();
|
||||
}
|
||||
else
|
||||
{
|
||||
invers.Invert();
|
||||
}
|
||||
return invers;
|
||||
}
|
||||
|
||||
TSE::Matrix4x4 mulsse(const TSE::Matrix4x4& A, const TSE::Matrix4x4& B)
|
||||
{
|
||||
using namespace TSE;
|
||||
Matrix4x4 C;
|
||||
|
||||
const __m128 b0 = _mm_loadu_ps(&B.m[0][0]);
|
||||
const __m128 b1 = _mm_loadu_ps(&B.m[1][0]);
|
||||
const __m128 b2 = _mm_loadu_ps(&B.m[2][0]);
|
||||
const __m128 b3 = _mm_loadu_ps(&B.m[3][0]);
|
||||
|
||||
for (int r = 0; r < 4; ++r) {
|
||||
__m128 row;
|
||||
#if SIMD_HAS_FMA
|
||||
row = _mm_mul_ps(_mm_set1_ps(A.m[r][0]), b0);
|
||||
row = _mm_fmadd_ps(_mm_set1_ps(A.m[r][1]), b1, row);
|
||||
row = _mm_fmadd_ps(_mm_set1_ps(A.m[r][2]), b2, row);
|
||||
row = _mm_fmadd_ps(_mm_set1_ps(A.m[r][3]), b3, row);
|
||||
#else
|
||||
row = _mm_mul_ps(_mm_set1_ps(A.m[r][0]), b0);
|
||||
row = _mm_add_ps(row, _mm_mul_ps(_mm_set1_ps(A.m[r][1]), b1));
|
||||
row = _mm_add_ps(row, _mm_mul_ps(_mm_set1_ps(A.m[r][2]), b2));
|
||||
row = _mm_add_ps(row, _mm_mul_ps(_mm_set1_ps(A.m[r][3]), b3));
|
||||
#endif
|
||||
_mm_storeu_ps(&C.m[r][0], row);
|
||||
}
|
||||
return C;
|
||||
}
|
||||
|
||||
float hsum_ps(__m128 v) {
|
||||
__m128 shuf = _mm_movehdup_ps(v);
|
||||
__m128 sums = _mm_add_ps(v, shuf);
|
||||
shuf = _mm_movehl_ps(shuf, sums);
|
||||
sums = _mm_add_ss(sums, shuf);
|
||||
return _mm_cvtss_f32(sums);
|
||||
}
|
||||
|
||||
TSE::Matrix4x4 TSE::Matrix4x4::operator*(const Matrix4x4 &other) const
|
||||
{
|
||||
return mulsse(*this, other);
|
||||
}
|
||||
|
||||
TSE::Matrix4x4 TSE::Matrix4x4::operator*=(const Matrix4x4 &other)
|
||||
{
|
||||
*this = *this * other;
|
||||
return *this;
|
||||
}
|
||||
|
||||
TSE::Matrix4x4 TSE::Matrix4x4::operator*(float scalar) const
|
||||
{
|
||||
Matrix4x4 R;
|
||||
|
||||
#if defined(__SSE__)
|
||||
const __m128 s = _mm_set1_ps(scalar);
|
||||
for (int r = 0; r < 4; ++r) {
|
||||
__m128 row = _mm_loadu_ps(&m[r][0]);
|
||||
row = _mm_mul_ps(row, s);
|
||||
_mm_storeu_ps(&R.m[r][0], row);
|
||||
}
|
||||
#else
|
||||
for (int r = 0; r < 4; ++r)
|
||||
for (int c = 0; c < 4; ++c)
|
||||
R.m[r][c] = m[r][c] * scalar;
|
||||
#endif
|
||||
|
||||
return R;
|
||||
}
|
||||
|
||||
TSE::Matrix4x4 TSE::Matrix4x4::operator*=(float scalar)
|
||||
{
|
||||
*this = *this * scalar;
|
||||
return *this;
|
||||
}
|
||||
|
||||
TSE::Vector3 TSE::Matrix4x4::operator*(const Vector3 &v) const
|
||||
{
|
||||
#if defined(__SSE__)
|
||||
const __m128 vec = _mm_set_ps(1.0f, v.z, v.y, v.x);
|
||||
|
||||
__m128 r0 = _mm_loadu_ps(&m[0][0]);
|
||||
__m128 r1 = _mm_loadu_ps(&m[1][0]);
|
||||
__m128 r2 = _mm_loadu_ps(&m[2][0]);
|
||||
#if SIMD_HAS_DPPS
|
||||
float x = _mm_cvtss_f32(_mm_dp_ps(r0, vec, 0xF1));
|
||||
float y = _mm_cvtss_f32(_mm_dp_ps(r1, vec, 0xF1));
|
||||
float z = _mm_cvtss_f32(_mm_dp_ps(r2, vec, 0xF1));
|
||||
#else
|
||||
float x = hsum_ps(_mm_mul_ps(r0, vec));
|
||||
float y = hsum_ps(_mm_mul_ps(r1, vec));
|
||||
float z = hsum_ps(_mm_mul_ps(r2, vec));
|
||||
#endif
|
||||
return Vector3{ x, y, z };
|
||||
#else
|
||||
return Vector3{
|
||||
m[0][0]*v.x + m[0][1]*v.y + m[0][2]*v.z + m[0][3],
|
||||
m[1][0]*v.x + m[1][1]*v.y + m[1][2]*v.z + m[1][3],
|
||||
m[2][0]*v.x + m[2][1]*v.y + m[2][2]*v.z + m[2][3]
|
||||
};
|
||||
#endif
|
||||
}
|
||||
|
||||
TSE::Vector4 TSE::Matrix4x4::operator*(const Vector4 &v) const
|
||||
{
|
||||
#if defined(__SSE__)
|
||||
const __m128 vec = _mm_set_ps(v.w, v.z, v.y, v.x);
|
||||
|
||||
__m128 r0 = _mm_loadu_ps(&m[0][0]);
|
||||
__m128 r1 = _mm_loadu_ps(&m[1][0]);
|
||||
__m128 r2 = _mm_loadu_ps(&m[2][0]);
|
||||
__m128 r3 = _mm_loadu_ps(&m[3][0]);
|
||||
|
||||
#if SIMD_HAS_DPPS
|
||||
float x = _mm_cvtss_f32(_mm_dp_ps(r0, vec, 0xF1));
|
||||
float y = _mm_cvtss_f32(_mm_dp_ps(r1, vec, 0xF1));
|
||||
float z = _mm_cvtss_f32(_mm_dp_ps(r2, vec, 0xF1));
|
||||
float w = _mm_cvtss_f32(_mm_dp_ps(r3, vec, 0xF1));
|
||||
#else
|
||||
float x = hsum_ps(_mm_mul_ps(r0, vec));
|
||||
float y = hsum_ps(_mm_mul_ps(r1, vec));
|
||||
float z = hsum_ps(_mm_mul_ps(r2, vec));
|
||||
float w = hsum_ps(_mm_mul_ps(r3, vec));
|
||||
#endif
|
||||
return Vector4{ x, y, z, w };
|
||||
#else
|
||||
return Vector4{
|
||||
m[0][0]*v.x + m[0][1]*v.y + m[0][2]*v.z + m[0][3]*v.w,
|
||||
m[1][0]*v.x + m[1][1]*v.y + m[1][2]*v.z + m[1][3]*v.w,
|
||||
m[2][0]*v.x + m[2][1]*v.y + m[2][2]*v.z + m[2][3]*v.w,
|
||||
m[3][0]*v.x + m[3][1]*v.y + m[3][2]*v.z + m[3][3]*v.w
|
||||
};
|
||||
#endif
|
||||
}
|
||||
96
TSE_Math/src/Matrix4x4.hpp
Normal file
96
TSE_Math/src/Matrix4x4.hpp
Normal file
@@ -0,0 +1,96 @@
|
||||
#pragma once
|
||||
|
||||
#include "Vector3.hpp"
|
||||
#include "Vector4.hpp"
|
||||
#include "Quaternion.hpp"
|
||||
|
||||
namespace TSE
|
||||
{
|
||||
class Matrix4x4
|
||||
{
|
||||
public:
|
||||
float m[4][4]; // Row Major Layout
|
||||
|
||||
/// @brief default Constructor. all values are 0
|
||||
Matrix4x4();
|
||||
/// @brief sets the diagonal to a custom value
|
||||
/// @param d the value for the diagonal
|
||||
Matrix4x4(float d);
|
||||
/// @brief copy constructor
|
||||
/// @param other the matrix to be copied
|
||||
Matrix4x4(const Matrix4x4& other);
|
||||
|
||||
/// @brief checks if the matrix is an identity matrix aka the diagonal is set to 1, and everithing else is 0
|
||||
/// @return is identity matrix
|
||||
bool IsIdentityMatrix() const;
|
||||
/// @brief chacks if the matrix ist valid aka the values are not NaN
|
||||
/// @return is valid
|
||||
bool IsValid() const;
|
||||
/// @brief inverts the current matrix with the generic invertion method
|
||||
void Invert();
|
||||
/// @brief gets the conjuget of the current matrix
|
||||
/// @return the conjuget
|
||||
Matrix4x4 Conjucate() const;
|
||||
/// @brief Gets the determinant of the matrix
|
||||
/// @return the determinant
|
||||
float Determinant() const;
|
||||
/// @brief checks if the current matrix is an affine matrix aka a transformation matrix only translation, rotation, and scale set.
|
||||
/// @return is affine
|
||||
bool IsAffine() const;
|
||||
/// @brief inverts an affine matrix. simply a faster inversion method for affine matrecies.
|
||||
void InvertAffine();
|
||||
/// @brief gets the pointer to the contents of this matrix.
|
||||
/// @return the contens as row major
|
||||
const float* ToArrayRowMajor() const;
|
||||
/// @brief fills an array with the matrix contens as column major
|
||||
/// @param out the array to be filled
|
||||
void ToArrayColumnMajor(float out[16]) const;
|
||||
|
||||
/// @brief generates an identity matrix
|
||||
/// @return identity matrix
|
||||
static Matrix4x4 Identity();
|
||||
/// @brief generates an orthographics projection matrix.
|
||||
/// @param left the left clipping plane
|
||||
/// @param right the right clipping plane
|
||||
/// @param bottom the bottom clipping plane
|
||||
/// @param top the top clipping plane
|
||||
/// @param near the near clipping plane
|
||||
/// @param far the far clipping plane
|
||||
/// @return an orthoraphic projection matrix
|
||||
static Matrix4x4 Orthographic(float left, float right, float bottom, float top, float near, float far);
|
||||
/// @brief generates a perspectiv projection marix
|
||||
/// @param fov the field of view in deg
|
||||
/// @param aspectRatio the aspect ratio of the render target
|
||||
/// @param near the near clipping plane
|
||||
/// @param far the far clipping plane
|
||||
/// @return a perspective projection matrix
|
||||
static Matrix4x4 Perspective(float fov, float aspectRatio, float near, float far);
|
||||
/// @brief generaties a translation matrix from a position
|
||||
/// @param pos the position to use
|
||||
/// @return the generated matrix
|
||||
static Matrix4x4 ToTranslationMatrix(const Vector3& pos);
|
||||
/// @brief generates a rotation matrix from a quaternion
|
||||
/// @param rot the quaternion to use
|
||||
/// @return the generated matrix
|
||||
static Matrix4x4 ToRotationMatrix(const Quaternion& rot);
|
||||
/// @brief generates a rotation matrix from an angle around the z axis (2D)
|
||||
/// @param angle the angle to rotate about
|
||||
/// @return the generated matrix
|
||||
static Matrix4x4 ToRotationMatrixFromZAxisOnly(float angle);
|
||||
/// @brief generates a scale matrix from a scale vector
|
||||
/// @param scale the scale to use
|
||||
/// @return the generated matrix
|
||||
static Matrix4x4 ToScaleMatrix(const Vector3& scale);
|
||||
/// @brief inverts a the given matrix, when possible it trys to use less calculations
|
||||
/// @param mat the matrix to invert
|
||||
/// @return the inverted matrix
|
||||
static Matrix4x4 Invert(const Matrix4x4& mat);
|
||||
|
||||
Matrix4x4 operator*(const Matrix4x4& other) const;
|
||||
Matrix4x4 operator*=(const Matrix4x4& other);
|
||||
Matrix4x4 operator*(float scalar) const;
|
||||
Matrix4x4 operator*=(float scalar);
|
||||
Vector3 operator*(const Vector3& v) const;
|
||||
Vector4 operator*(const Vector4& v) const;
|
||||
};
|
||||
} // namespace TSE
|
||||
78
TSE_Math/src/Mesh.cpp
Normal file
78
TSE_Math/src/Mesh.cpp
Normal file
@@ -0,0 +1,78 @@
|
||||
#include "Mesh.hpp"
|
||||
#include "MathF.hpp"
|
||||
#include <cmath>
|
||||
|
||||
TSE::Mesh::Mesh()
|
||||
{
|
||||
name = "";
|
||||
}
|
||||
|
||||
TSE::Mesh::Mesh(string _name, const std::vector<Vector3> &_vertecies, const std::vector<ushort> &_indecies, const std::vector<Vector2> &_uvs)
|
||||
{
|
||||
name = _name;
|
||||
vertecies = std::move(_vertecies);
|
||||
indecies = std::move(_indecies);
|
||||
uvs = std::move(_uvs);
|
||||
}
|
||||
|
||||
size_t TSE::Mesh::IndeciesCount() const
|
||||
{
|
||||
return indecies.size();
|
||||
}
|
||||
|
||||
size_t TSE::Mesh::VerteciesCount() const
|
||||
{
|
||||
return vertecies.size();
|
||||
}
|
||||
|
||||
TSE::Mesh TSE::Mesh::GetCircleMesh(ushort segments)
|
||||
{
|
||||
std::vector<Vector3> verts;
|
||||
std::vector<ushort> indices;
|
||||
std::vector<Vector2> uvs;
|
||||
|
||||
verts.emplace_back(0.0f, 0.0f, 0.0f);
|
||||
uvs.emplace_back(0.5f, 0.5f);
|
||||
|
||||
float angleStep = 2.0f * TSE_PI / segments;
|
||||
|
||||
for (int i = 0; i <= segments; ++i) {
|
||||
float angle = i * angleStep;
|
||||
float x = std::cos(angle) * 0.5f;
|
||||
float y = std::sin(angle) * 0.5f;
|
||||
verts.emplace_back(x, y, 0);
|
||||
uvs.emplace_back(x + 0.5f, y + 0.5f);
|
||||
|
||||
if (i > 0) {
|
||||
indices.push_back(0);
|
||||
indices.push_back(i);
|
||||
indices.push_back(i + 1);
|
||||
}
|
||||
}
|
||||
|
||||
return Mesh("Circle", verts, indices, uvs);
|
||||
}
|
||||
|
||||
TSE::Mesh TSE::Mesh::GetQuadMesh()
|
||||
{
|
||||
std::vector<Vector3> verts = {
|
||||
Vector3(-0.5f, -0.5f, 0),
|
||||
Vector3( 0.5f, -0.5f, 0),
|
||||
Vector3( 0.5f, 0.5f, 0),
|
||||
Vector3(-0.5f, 0.5f, 0)
|
||||
};
|
||||
|
||||
std::vector<Vector2> uvs = {
|
||||
Vector2(0.0f, 0.0f),
|
||||
Vector2(1.0f, 0.0f),
|
||||
Vector2(1.0f, 1.0f),
|
||||
Vector2(0.0f, 1.0f)
|
||||
};
|
||||
|
||||
std::vector<unsigned short> indices = {
|
||||
0, 1, 2,
|
||||
2, 3, 0
|
||||
};
|
||||
|
||||
return Mesh("Quad", verts, indices, uvs);
|
||||
}
|
||||
45
TSE_Math/src/Mesh.hpp
Normal file
45
TSE_Math/src/Mesh.hpp
Normal file
@@ -0,0 +1,45 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include "Types.hpp"
|
||||
#include "Vector3.hpp"
|
||||
#include "Vector2.hpp"
|
||||
|
||||
namespace TSE
|
||||
{
|
||||
class Mesh
|
||||
{
|
||||
public:
|
||||
string name;
|
||||
|
||||
std::vector<Vector3> vertecies;
|
||||
std::vector<ushort> indecies;
|
||||
std::vector<Vector2> uvs;
|
||||
|
||||
/// @brief gives you an empty mesh with the name set to an empty string
|
||||
Mesh();
|
||||
/// @brief constructs a mesh with custom parameters
|
||||
/// @param _name name of the mesh
|
||||
/// @param _vertecies the vertecies
|
||||
/// @param _indecies the indecies
|
||||
/// @param _uvs the uvs
|
||||
Mesh(string _name,
|
||||
const std::vector<Vector3>& _vertecies,
|
||||
const std::vector<ushort>& _indecies,
|
||||
const std::vector<Vector2>& _uvs);
|
||||
/// @brief gives you the count of indecies in this mesh
|
||||
/// @return the indecie count
|
||||
size_t IndeciesCount() const;
|
||||
/// @brief gives you the count of vertecies in this mesh
|
||||
/// @return the vertex count
|
||||
size_t VerteciesCount() const;
|
||||
|
||||
/// @brief generates a circle mesh with the defined amounts of segments
|
||||
/// @param segments amount of "pizza slices" to make the mesh out of. default 16
|
||||
/// @return the resulting mesh
|
||||
static Mesh GetCircleMesh(ushort segments = 16);
|
||||
/// @brief gives you a basic unit quad with (-0.5, -0.5) -> (0.5, 0.5)
|
||||
/// @return the resulting mesh
|
||||
static Mesh GetQuadMesh();
|
||||
};
|
||||
} // namespace TSE
|
||||
137
TSE_Math/src/Quaternion.cpp
Normal file
137
TSE_Math/src/Quaternion.cpp
Normal file
@@ -0,0 +1,137 @@
|
||||
#include "Quaternion.hpp"
|
||||
#include "Vector4.hpp"
|
||||
#include "Vector3.hpp"
|
||||
#include "MathF.hpp"
|
||||
#include <cmath>
|
||||
|
||||
TSE::Quaternion::Quaternion() { }
|
||||
|
||||
TSE::Quaternion::Quaternion(float _x, float _y, float _z, float _w)
|
||||
{
|
||||
x = _x;
|
||||
y = _y;
|
||||
z = _z;
|
||||
w = _w;
|
||||
}
|
||||
|
||||
TSE::Quaternion::Quaternion(const Quaternion &other)
|
||||
{
|
||||
x = other.x;
|
||||
y = other.y;
|
||||
z = other.z;
|
||||
w = other.w;
|
||||
}
|
||||
|
||||
TSE::Quaternion::Quaternion(const Vector4 &other)
|
||||
{
|
||||
x = other.x;
|
||||
y = other.y;
|
||||
z = other.z;
|
||||
w = other.w;
|
||||
}
|
||||
|
||||
TSE::Vector3 TSE::Quaternion::ToEulerAngles() const
|
||||
{
|
||||
Vector3 euler;
|
||||
|
||||
float sinr_cosp = 2.0f * (w * x + y * z);
|
||||
float cosr_cosp = 1.0f - 2.0f * (x * x + y * y);
|
||||
euler.x = Rad2Deg(std::atan2(sinr_cosp, cosr_cosp));
|
||||
|
||||
float sinp = 2.0f * (w * y - z * x);
|
||||
if (std::abs(sinp) >= 1)
|
||||
euler.y = Rad2Deg(std::copysign(TSE_PI / 2.0f, sinp));
|
||||
else
|
||||
euler.y = Rad2Deg(std::asin(sinp));
|
||||
|
||||
float siny_cosp = 2.0f * (w * z + x * y);
|
||||
float cosy_cosp = 1.0f - 2.0f * (y * y + z * z);
|
||||
euler.z = Rad2Deg(std::atan2(siny_cosp, cosy_cosp));
|
||||
|
||||
return euler;
|
||||
}
|
||||
|
||||
TSE::Vector3 TSE::Quaternion::Rotate(const Vector3 &v) const
|
||||
{
|
||||
Vector3 qv(x, y, z);
|
||||
Vector3 t = Vector3::Cross(qv, v) * 2.0f;
|
||||
return v + t * w + Vector3::Cross(qv, t);
|
||||
}
|
||||
|
||||
void TSE::Quaternion::Normalize()
|
||||
{
|
||||
float lensq = w*w + x*x + y*y + z*z;
|
||||
if(lensq <= TSE_EPSILON) return;
|
||||
const float inv = 1.0f / std::sqrt(lensq);
|
||||
x *= inv; y *= inv; z *= inv; w *= inv;
|
||||
}
|
||||
|
||||
TSE::Quaternion TSE::Quaternion::FromAngleAxis(float angleRad, const Vector3 &axis)
|
||||
{
|
||||
Vector3 a = Vector3::Normalize(axis);
|
||||
float half = angleRad * 0.5f;
|
||||
float s = sin(half);
|
||||
|
||||
Quaternion q;
|
||||
q.w = std::cos(half);
|
||||
q.x = a.x * s;
|
||||
q.y = a.y * s;
|
||||
q.z = a.z * s;
|
||||
|
||||
q.Normalize();
|
||||
|
||||
return q;
|
||||
}
|
||||
|
||||
TSE::Quaternion TSE::Quaternion::FromEulerAngles(const Vector3 &euler)
|
||||
{
|
||||
float roll = Deg2Rad(euler.x);
|
||||
float pitch = Deg2Rad(euler.y);
|
||||
float yaw = Deg2Rad(euler.z);
|
||||
|
||||
float cr = std::cos(roll * 0.5f);
|
||||
float sr = std::sin(roll * 0.5f);
|
||||
float cp = std::cos(pitch * 0.5f);
|
||||
float sp = std::sin(pitch * 0.5f);
|
||||
float cy = std::cos(yaw * 0.5f);
|
||||
float sy = std::sin(yaw * 0.5f);
|
||||
|
||||
return Quaternion(
|
||||
sr * cp * cy - cr * sp * sy,
|
||||
cr * sp * cy + sr * cp * sy,
|
||||
cr * cp * sy - sr * sp * cy,
|
||||
cr * cp * cy + sr * sp * sy
|
||||
);
|
||||
}
|
||||
|
||||
TSE::Vector3 TSE::Quaternion::ToEulerAngles(const Quaternion &q)
|
||||
{
|
||||
return q.ToEulerAngles();
|
||||
}
|
||||
|
||||
TSE::Quaternion TSE::Quaternion::operator*(const Quaternion &other) const
|
||||
{
|
||||
Quaternion b = *this;
|
||||
Quaternion r;
|
||||
r.w = b.w*other.w - b.x*other.x - b.y*other.y - b.z*other.z;
|
||||
r.x = b.w*other.x + b.x*other.w + b.y*other.z - b.z*other.y;
|
||||
r.y = b.w*other.y - b.x*other.z + b.y*other.w + b.z*other.x;
|
||||
r.z = b.w*other.z + b.x*other.y - b.y*other.x + b.z*other.w;
|
||||
return r;
|
||||
}
|
||||
|
||||
TSE::Quaternion TSE::Quaternion::operator*=(const Quaternion &other)
|
||||
{
|
||||
*this = *this * other;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool TSE::Quaternion::operator==(const Quaternion &other) const
|
||||
{
|
||||
return x == other.x && y == other.y && z == other.z && w == other.w;
|
||||
}
|
||||
|
||||
bool TSE::Quaternion::operator!=(const Quaternion &other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
69
TSE_Math/src/Quaternion.hpp
Normal file
69
TSE_Math/src/Quaternion.hpp
Normal file
@@ -0,0 +1,69 @@
|
||||
#pragma once
|
||||
|
||||
#include "Types.hpp"
|
||||
|
||||
namespace TSE
|
||||
{
|
||||
class Vector3;
|
||||
class Vector4;
|
||||
|
||||
class Quaternion
|
||||
{
|
||||
public:
|
||||
#pragma region members
|
||||
float x = 0, y = 0, z = 0, w = 1;
|
||||
#pragma endregion members
|
||||
|
||||
#pragma region ctor
|
||||
/// @brief constructs a default Quaternion
|
||||
Quaternion();
|
||||
/// @brief constructs a Quaternion with given values
|
||||
/// @param _x the x component
|
||||
/// @param _y the y component
|
||||
/// @param _z the z component
|
||||
/// @param _w the w component
|
||||
Quaternion(float _x, float _y, float _z, float _w);
|
||||
/// @brief copy constructor
|
||||
/// @param other the quaternion to be copied
|
||||
Quaternion(const Quaternion& other);
|
||||
/// @brief conversion constructor
|
||||
/// @param other the vector4 to be converted
|
||||
Quaternion(const Vector4& other);
|
||||
#pragma endregion ctor
|
||||
|
||||
#pragma region methods
|
||||
/// @brief converts the Quaternion to a Vector3 with yaw, pitch, and roll
|
||||
/// @return the euler angles
|
||||
Vector3 ToEulerAngles() const;
|
||||
/// @brief rotates a point with the quaternion
|
||||
/// @param v the point to rotate
|
||||
/// @return the rotated point
|
||||
Vector3 Rotate(const Vector3& v) const;
|
||||
/// @brief normalizes the current quaternion
|
||||
void Normalize();
|
||||
|
||||
#pragma region static
|
||||
/// @brief gives you a quaternion based on an angle axis input
|
||||
/// @param angleRad the angle in radiants
|
||||
/// @param axis the axis to ratate around
|
||||
/// @return the resulting quaternion
|
||||
static Quaternion FromAngleAxis(float angleRad, const Vector3& axis);
|
||||
/// @brief gives you a quaternion based on euler angles
|
||||
/// @param euler the euler angles
|
||||
/// @return the resulting quaternion
|
||||
static Quaternion FromEulerAngles(const Vector3& euler);
|
||||
/// @brief converts a Quaternion to a Vector3 with yaw, pitch, and roll
|
||||
/// @param q the quaternion to convert
|
||||
/// @return the euler angles
|
||||
static Vector3 ToEulerAngles(const Quaternion& q);
|
||||
#pragma endregion static
|
||||
|
||||
#pragma region operators
|
||||
Quaternion operator*(const Quaternion& other) const;
|
||||
Quaternion operator*=(const Quaternion& other);
|
||||
bool operator==(const Quaternion& other) const;
|
||||
bool operator!=(const Quaternion& other) const;
|
||||
#pragma endregion operators
|
||||
#pragma endregion methods
|
||||
};
|
||||
} // namespace TSE
|
||||
56
TSE_Math/src/Rect.cpp
Normal file
56
TSE_Math/src/Rect.cpp
Normal file
@@ -0,0 +1,56 @@
|
||||
#include "Rect.hpp"
|
||||
|
||||
TSE::Rect::Rect()
|
||||
{
|
||||
p1 = {0,0};
|
||||
p2 = {0,0};
|
||||
}
|
||||
|
||||
TSE::Rect::Rect(float x1, float y1, float x2, float y2)
|
||||
{
|
||||
p1 = {x1, y1};
|
||||
p2 = {x2, y2};
|
||||
}
|
||||
|
||||
TSE::Rect::Rect(const Vector2 &_p1, const Vector2 &_p2)
|
||||
{
|
||||
p1 = Vector2(_p1);
|
||||
p2 = Vector2(_p2);
|
||||
}
|
||||
|
||||
TSE::Rect::Rect(const Vector4 &v)
|
||||
{
|
||||
p1 = {v.x, v.y};
|
||||
p1 = {v.z, v.w};
|
||||
}
|
||||
|
||||
TSE::Rect::Rect(const Rect &r)
|
||||
{
|
||||
p1 = Vector2(r.p1);
|
||||
p2 = Vector2(r.p2);
|
||||
}
|
||||
|
||||
float TSE::Rect::width() const
|
||||
{
|
||||
return std::abs(p2.x - p1.x);
|
||||
}
|
||||
|
||||
float TSE::Rect::height() const
|
||||
{
|
||||
return std::abs(p2.y - p1.y);
|
||||
}
|
||||
|
||||
float TSE::Rect::area() const
|
||||
{
|
||||
return width() * height();
|
||||
}
|
||||
|
||||
bool TSE::Rect::operator==(const Rect &other) const
|
||||
{
|
||||
return p1 == other.p1 && p2 == other.p2;
|
||||
}
|
||||
|
||||
bool TSE::Rect::operator!=(const Rect &other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
48
TSE_Math/src/Rect.hpp
Normal file
48
TSE_Math/src/Rect.hpp
Normal file
@@ -0,0 +1,48 @@
|
||||
#pragma once
|
||||
|
||||
#include "Vector2.hpp"
|
||||
#include "Vector4.hpp"
|
||||
#include "Types.hpp"
|
||||
#include <vector>
|
||||
|
||||
namespace TSE
|
||||
{
|
||||
class Rect
|
||||
{
|
||||
public:
|
||||
Vector2 p1, p2;
|
||||
|
||||
/// @brief default constructer wicht all points starting at (0,0)
|
||||
Rect();
|
||||
/// @brief constructor with floats for custom values
|
||||
/// @param x1 x component of min
|
||||
/// @param y1 y component of min
|
||||
/// @param x2 x component of max
|
||||
/// @param y2 y component of max
|
||||
Rect(float x1, float y1, float x2, float y2);
|
||||
/// @brief constructer with Vector2 for custom values
|
||||
/// @param _p1 min
|
||||
/// @param _p2 max
|
||||
Rect(const Vector2& _p1, const Vector2& _p2);
|
||||
/// @brief constructor wich Vector4 for custom Values
|
||||
/// @param v min -> (x,y) max -> (z,w)
|
||||
Rect(const Vector4& v);
|
||||
/// @brief copy constructor
|
||||
/// @param r the rect to me copied
|
||||
Rect(const Rect& r);
|
||||
|
||||
/// @brief gives you the current width of the rect
|
||||
/// @return the width in local rect space
|
||||
float width() const;
|
||||
/// @brief gives you the current height of the rect
|
||||
/// @return the height in local rect space
|
||||
float height() const;
|
||||
/// @brief gives you the area of the rect based on the height() and width() functions
|
||||
/// @return the area in local rect space
|
||||
float area() const;
|
||||
|
||||
bool operator==(const Rect& other) const;
|
||||
bool operator!=(const Rect& other) const;
|
||||
|
||||
};
|
||||
} // namespace TSE
|
||||
24
TSE_Math/src/TransformationStack.cpp
Normal file
24
TSE_Math/src/TransformationStack.cpp
Normal file
@@ -0,0 +1,24 @@
|
||||
#include "TransformationStack.hpp"
|
||||
|
||||
TSE::TransformationStack::TransformationStack()
|
||||
{
|
||||
stack.push_back(Matrix4x4::Identity());
|
||||
}
|
||||
|
||||
const TSE::Matrix4x4 &TSE::TransformationStack::Top() const
|
||||
{
|
||||
return stack.back();
|
||||
}
|
||||
|
||||
void TSE::TransformationStack::Push(const Matrix4x4 &matrix)
|
||||
{
|
||||
stack.push_back(Top() * matrix);
|
||||
}
|
||||
|
||||
void TSE::TransformationStack::Pop()
|
||||
{
|
||||
if (stack.size() > 1)
|
||||
{
|
||||
stack.pop_back();
|
||||
}
|
||||
}
|
||||
25
TSE_Math/src/TransformationStack.hpp
Normal file
25
TSE_Math/src/TransformationStack.hpp
Normal file
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include "Matrix4x4.hpp"
|
||||
|
||||
namespace TSE
|
||||
{
|
||||
class TransformationStack
|
||||
{
|
||||
private:
|
||||
std::vector<Matrix4x4> stack;
|
||||
|
||||
public:
|
||||
/// @brief generates an empty transformation stack, based on an identity matrix
|
||||
TransformationStack();
|
||||
/// @brief gets the current value of the stack
|
||||
/// @return the current value
|
||||
const Matrix4x4& Top() const;
|
||||
/// @brief pusches a new value on to the stack
|
||||
/// @param matrix the value to be pusched
|
||||
void Push(const Matrix4x4& matrix);
|
||||
/// @brief pops the last value off the stack
|
||||
void Pop();
|
||||
};
|
||||
} // namespace TSE
|
||||
217
TSE_Math/src/Vector2.cpp
Normal file
217
TSE_Math/src/Vector2.cpp
Normal file
@@ -0,0 +1,217 @@
|
||||
#include "Vector2.hpp"
|
||||
#include "Vector3.hpp"
|
||||
#include "Vector4.hpp"
|
||||
#include "MathF.hpp"
|
||||
#include <cmath>
|
||||
|
||||
const TSE::Vector2 TSE::Vector2::left = TSE::Vector2(-1,0);
|
||||
const TSE::Vector2 TSE::Vector2::right = TSE::Vector2(1,0);
|
||||
const TSE::Vector2 TSE::Vector2::up = TSE::Vector2(0,1);
|
||||
const TSE::Vector2 TSE::Vector2::down = TSE::Vector2(0,-1);
|
||||
const TSE::Vector2 TSE::Vector2::one = TSE::Vector2(1,1);
|
||||
const TSE::Vector2 TSE::Vector2::zero = TSE::Vector2(0,0);
|
||||
|
||||
TSE::Vector2::Vector2() { }
|
||||
|
||||
TSE::Vector2::Vector2(float _x, float _y)
|
||||
{
|
||||
x = _x;
|
||||
y = _y;
|
||||
}
|
||||
|
||||
TSE::Vector2::Vector2(const Vector2 &other)
|
||||
{
|
||||
x = other.x;
|
||||
y = other.y;
|
||||
}
|
||||
|
||||
TSE::Vector2::Vector2(const Vector3 &other)
|
||||
{
|
||||
x = other.x;
|
||||
y = other.y;
|
||||
}
|
||||
|
||||
TSE::Vector2::Vector2(const Vector4 &other)
|
||||
{
|
||||
x = other.x;
|
||||
y = other.y;
|
||||
}
|
||||
|
||||
float TSE::Vector2::Length() const
|
||||
{
|
||||
return std::sqrt(x*x + y*y);
|
||||
}
|
||||
|
||||
float TSE::Vector2::LengthSqr() const
|
||||
{
|
||||
return x*x + y*y;
|
||||
}
|
||||
|
||||
bool TSE::Vector2::IsValid() const
|
||||
{
|
||||
return !std::isnan(x) && !std::isnan(y);
|
||||
}
|
||||
|
||||
void TSE::Vector2::Normalize()
|
||||
{
|
||||
float lensq = LengthSqr();
|
||||
if(lensq <= TSE_EPSILON) return;
|
||||
const float inv = 1.0f / std::sqrt(lensq);
|
||||
x *= inv; y *= inv;
|
||||
}
|
||||
|
||||
void TSE::Vector2::NormalizeSafe(const Vector2 &fallback)
|
||||
{
|
||||
float lensq = LengthSqr();
|
||||
if(lensq <= TSE_EPSILON)
|
||||
{
|
||||
*this = fallback;
|
||||
return;
|
||||
}
|
||||
const float inv = 1.0f / std::sqrt(lensq);
|
||||
x *= inv; y *= inv;
|
||||
if(!IsValid())
|
||||
{
|
||||
*this = fallback;
|
||||
}
|
||||
}
|
||||
|
||||
TSE::string TSE::Vector2::ToString() const
|
||||
{
|
||||
return "(" + std::to_string(x) + "|" + std::to_string(y) + ")";
|
||||
}
|
||||
|
||||
TSE::Vector3 TSE::Vector2::ToVector3() const
|
||||
{
|
||||
return Vector3(x,y,0);
|
||||
}
|
||||
|
||||
TSE::Vector4 TSE::Vector2::ToVector4() const
|
||||
{
|
||||
return Vector4(x,y,0,0);
|
||||
}
|
||||
|
||||
float TSE::Vector2::Distance(const Vector2 &a, const Vector2 &b)
|
||||
{
|
||||
return (a - b).Length();
|
||||
}
|
||||
|
||||
float TSE::Vector2::DistanceSqr(const Vector2 &a, const Vector2 &b)
|
||||
{
|
||||
return (a - b).LengthSqr();
|
||||
}
|
||||
|
||||
TSE::Vector2 TSE::Vector2::Normalize(const Vector2 &v)
|
||||
{
|
||||
Vector2 result = v;
|
||||
result.Normalize();
|
||||
return result;
|
||||
}
|
||||
|
||||
TSE::Vector2 TSE::Vector2::NormalizeSafe(const Vector2 &v, const Vector2 &fallback)
|
||||
{
|
||||
Vector2 result = v;
|
||||
result.NormalizeSafe(fallback);
|
||||
return result;
|
||||
}
|
||||
|
||||
TSE::Vector2 TSE::Vector2::Lerp(const Vector2 &a, const Vector2 &b, float t)
|
||||
{
|
||||
return a + (b - a) * t;
|
||||
}
|
||||
|
||||
TSE::Vector2 TSE::Vector2::Berp(const Vector2 &a, const Vector2 &b, const Vector2 &c, float t)
|
||||
{
|
||||
return Lerp(Lerp(a, b, t), Lerp(b, c, t), t);
|
||||
}
|
||||
|
||||
TSE::Vector2 TSE::Vector2::Midpoint(const Vector2 &a, const Vector2 &b)
|
||||
{
|
||||
return (a + b) / 2.0f;
|
||||
}
|
||||
|
||||
float TSE::Vector2::Dot(const Vector2 &a, const Vector2 &b)
|
||||
{
|
||||
return a.x * b.x + a.y * b.y;
|
||||
}
|
||||
|
||||
float TSE::Vector2::Cross(const Vector2 &a, const Vector2 &b)
|
||||
{
|
||||
return a.x * b.y - a.y * b.x;
|
||||
}
|
||||
|
||||
TSE::Vector2 TSE::Vector2::operator+(const Vector2 &other) const
|
||||
{
|
||||
return Vector2(x + other.x, y + other.y);
|
||||
}
|
||||
|
||||
TSE::Vector2 TSE::Vector2::operator+=(const Vector2 &other)
|
||||
{
|
||||
*this = *this + other;
|
||||
return *this;
|
||||
}
|
||||
|
||||
TSE::Vector2 TSE::Vector2::operator-(const Vector2 &other) const
|
||||
{
|
||||
return Vector2(x - other.x, y - other.y);
|
||||
}
|
||||
|
||||
TSE::Vector2 TSE::Vector2::operator-=(const Vector2 &other)
|
||||
{
|
||||
*this = *this - other;
|
||||
return *this;
|
||||
}
|
||||
|
||||
TSE::Vector2 TSE::Vector2::operator*(const Vector2 &other) const
|
||||
{
|
||||
return Vector2(x * other.x, y * other.y);
|
||||
}
|
||||
|
||||
TSE::Vector2 TSE::Vector2::operator*=(const Vector2 &other)
|
||||
{
|
||||
*this = *this * other;
|
||||
return *this;
|
||||
}
|
||||
|
||||
TSE::Vector2 TSE::Vector2::operator/(const Vector2 &other) const
|
||||
{
|
||||
return Vector2(x / other.x, y / other.y);
|
||||
}
|
||||
|
||||
TSE::Vector2 TSE::Vector2::operator/=(const Vector2 &other)
|
||||
{
|
||||
*this = *this / other;
|
||||
return *this;
|
||||
}
|
||||
|
||||
TSE::Vector2 TSE::Vector2::operator*(const float other) const
|
||||
{
|
||||
return Vector2(x * other, y * other);
|
||||
}
|
||||
|
||||
TSE::Vector2 TSE::Vector2::operator*=(const float other)
|
||||
{
|
||||
*this = *this * other;
|
||||
return *this;
|
||||
}
|
||||
|
||||
TSE::Vector2 TSE::Vector2::operator/(const float other) const
|
||||
{
|
||||
return Vector2(x / other, y / other);
|
||||
}
|
||||
|
||||
TSE::Vector2 TSE::Vector2::operator/=(const float other)
|
||||
{
|
||||
*this = *this / other;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool TSE::Vector2::operator==(const Vector2 &other) const
|
||||
{
|
||||
return x == other.x && y == other.y;
|
||||
}
|
||||
|
||||
bool TSE::Vector2::operator!=(const Vector2 &other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
137
TSE_Math/src/Vector2.hpp
Normal file
137
TSE_Math/src/Vector2.hpp
Normal file
@@ -0,0 +1,137 @@
|
||||
#pragma once
|
||||
|
||||
#include "Types.hpp"
|
||||
|
||||
namespace TSE
|
||||
{
|
||||
class Vector3;
|
||||
class Vector4;
|
||||
|
||||
class Vector2
|
||||
{
|
||||
public:
|
||||
#pragma region members
|
||||
float x = 0, y = 0;
|
||||
#pragma endregion members
|
||||
|
||||
#pragma region consts
|
||||
static const Vector2 left;
|
||||
static const Vector2 right;
|
||||
static const Vector2 up;
|
||||
static const Vector2 down;
|
||||
static const Vector2 one;
|
||||
static const Vector2 zero;
|
||||
#pragma endregion
|
||||
|
||||
#pragma region ctor
|
||||
/// @brief enpty constructor defined as (0,0)
|
||||
Vector2();
|
||||
/// @brief constructs a vector2 with custom values
|
||||
/// @param _x the x component
|
||||
/// @param _y the y component
|
||||
Vector2(float _x, float _y);
|
||||
/// @brief copy constructor
|
||||
/// @param other the vector2 to be copied from
|
||||
Vector2(const Vector2& other);
|
||||
/// @brief converter constructor. it converts a Vector3 to a Vector2 without encointing for the z component
|
||||
/// @param other the Vector3 to convert
|
||||
Vector2(const Vector3& other);
|
||||
/// @brief converter constructor. it converts a Vector4 to a Vector2 without encointing for the z, and w component
|
||||
/// @param other the Vector4 to convert
|
||||
Vector2(const Vector4& other);
|
||||
#pragma endregion ctor
|
||||
|
||||
#pragma region methods
|
||||
/// @brief the length of the vector
|
||||
/// @return the length
|
||||
float Length() const;
|
||||
/// @brief the length² of the vector
|
||||
/// @return the length²
|
||||
float LengthSqr() const;
|
||||
/// @brief checks if the individual components have valid values aka are not nan
|
||||
/// @return are the values valid
|
||||
bool IsValid() const;
|
||||
/// @brief normalizes the Vector2 to have a length of 1
|
||||
void Normalize();
|
||||
/// @brief normalizes the Vector2 to have a length of 1. If the current length of the vector is smaller then epsilon, it gives you the fallback value.
|
||||
/// @param fallback the value to set the vector to if the current length is smaller then epsilon
|
||||
void NormalizeSafe(const Vector2& fallback);
|
||||
/// @brief gives you the vector2 as a string representation. mostly for debugging
|
||||
/// @return the vector2 in a format like (x|y)
|
||||
string ToString() const;
|
||||
/// @brief creates a Vector3 with the same values as the Vector2, the y component gets the value 0
|
||||
/// @return the Vector2 as a Vector3
|
||||
Vector3 ToVector3() const;
|
||||
/// @brief creates a Vector4 with the same values as the Vector2, the y and w components get the value 0
|
||||
/// @return the Vector2 as a Vector4
|
||||
Vector4 ToVector4() const;
|
||||
|
||||
#pragma region static
|
||||
/// @brief gives you the distance between two vectors.
|
||||
/// @param a point 1
|
||||
/// @param b point 2
|
||||
/// @return the distance between point 1 and point 2
|
||||
static float Distance(const Vector2& a, const Vector2& b);
|
||||
/// @brief gives you the distance² between two vectors.
|
||||
/// @param a point 1
|
||||
/// @param b point 2
|
||||
/// @return the distance² between point 1 and point 2
|
||||
static float DistanceSqr(const Vector2& a, const Vector2& b);
|
||||
/// @brief normalizes a copy of the Vector2 to have a length of 1
|
||||
/// @param v the vector to be normaliezed
|
||||
/// @return a normalies copy of the vector
|
||||
static Vector2 Normalize(const Vector2& v);
|
||||
/// @brief normalizes a copy of the Vector2 to have a length of 1. If the current length of the vector is smaller then epsilon, it gives you the fallback value.
|
||||
/// @param fallback the value to set the vector to if the current length is smaller then epsilon
|
||||
/// @param v the vector to be normaliezed
|
||||
/// @return a normalies copy of the vector
|
||||
static Vector2 NormalizeSafe(const Vector2& v, const Vector2& fallback);
|
||||
/// @brief linearly interpolates between two points using t
|
||||
/// @param a point 1
|
||||
/// @param b point 2
|
||||
/// @param t the amoint to interpolate by
|
||||
/// @return the interpolated point
|
||||
static Vector2 Lerp(const Vector2& a, const Vector2& b, float t);
|
||||
/// @brief bezier interpolation using three points using t
|
||||
/// @param a point 1
|
||||
/// @param b controll point
|
||||
/// @param c point 2
|
||||
/// @param t the amoint to interpolate by
|
||||
/// @return the interpolated point
|
||||
static Vector2 Berp(const Vector2& a, const Vector2& b, const Vector2& c, float t);
|
||||
/// @brief gives you the midpoint between two points
|
||||
/// @param a point 1
|
||||
/// @param b point 2
|
||||
/// @return the midpoint
|
||||
static Vector2 Midpoint(const Vector2& a, const Vector2& b);
|
||||
/// @brief gives you the dot product between to vectors
|
||||
/// @param a vector 1
|
||||
/// @param b vector 2
|
||||
/// @return the dot product
|
||||
static float Dot(const Vector2& a, const Vector2& b);
|
||||
/// @brief it gives you the "2D Cross Product" (there is no real 2D Cross product, but this function is still usefull sometimes)
|
||||
/// @param a vector 1
|
||||
/// @param b vector 2
|
||||
/// @return 2D cross product
|
||||
static float Cross(const Vector2& a, const Vector2& b);
|
||||
#pragma endregion static
|
||||
|
||||
#pragma region operators
|
||||
Vector2 operator+(const Vector2& other) const;
|
||||
Vector2 operator+=(const Vector2& other);
|
||||
Vector2 operator-(const Vector2& other) const;
|
||||
Vector2 operator-=(const Vector2& other);
|
||||
Vector2 operator*(const Vector2& other) const;
|
||||
Vector2 operator*=(const Vector2& other);
|
||||
Vector2 operator/(const Vector2& other) const;
|
||||
Vector2 operator/=(const Vector2& other);
|
||||
Vector2 operator*(const float other) const;
|
||||
Vector2 operator*=(const float other);
|
||||
Vector2 operator/(const float other) const;
|
||||
Vector2 operator/=(const float other);
|
||||
bool operator==(const Vector2& other) const;
|
||||
bool operator!=(const Vector2& other) const;
|
||||
#pragma endregion operators
|
||||
#pragma endregion methods
|
||||
};
|
||||
} // namespace TSE
|
||||
233
TSE_Math/src/Vector3.cpp
Normal file
233
TSE_Math/src/Vector3.cpp
Normal file
@@ -0,0 +1,233 @@
|
||||
#include "Vector3.hpp"
|
||||
#include "Vector2.hpp"
|
||||
#include "Vector4.hpp"
|
||||
#include "MathF.hpp"
|
||||
#include <cmath>
|
||||
|
||||
const TSE::Vector3 TSE::Vector3::left = TSE::Vector3(-1,0,0);
|
||||
const TSE::Vector3 TSE::Vector3::right = TSE::Vector3(1,0,0);
|
||||
const TSE::Vector3 TSE::Vector3::up = TSE::Vector3(0,1,0);
|
||||
const TSE::Vector3 TSE::Vector3::down = TSE::Vector3(0,-1,0);
|
||||
const TSE::Vector3 TSE::Vector3::forward = TSE::Vector3(0,0,1);
|
||||
const TSE::Vector3 TSE::Vector3::back = TSE::Vector3(0,0,-1);
|
||||
const TSE::Vector3 TSE::Vector3::one = TSE::Vector3(1,1,1);
|
||||
const TSE::Vector3 TSE::Vector3::zero = TSE::Vector3(0,0,0);
|
||||
|
||||
TSE::Vector3::Vector3() { }
|
||||
|
||||
TSE::Vector3::Vector3(float _x, float _y)
|
||||
{
|
||||
x = _x;
|
||||
y = _y;
|
||||
z = 0;
|
||||
}
|
||||
|
||||
TSE::Vector3::Vector3(float _x, float _y, float _z)
|
||||
{
|
||||
x = _x;
|
||||
y = _y;
|
||||
z = _z;
|
||||
}
|
||||
|
||||
TSE::Vector3::Vector3(const Vector3 &other)
|
||||
{
|
||||
x = other.x;
|
||||
y = other.y;
|
||||
z = other.z;
|
||||
}
|
||||
|
||||
TSE::Vector3::Vector3(const Vector2 &other)
|
||||
{
|
||||
x = other.x;
|
||||
y = other.y;
|
||||
}
|
||||
|
||||
TSE::Vector3::Vector3(const Vector4 &other)
|
||||
{
|
||||
x = other.x;
|
||||
y = other.y;
|
||||
z = other.z;
|
||||
}
|
||||
|
||||
float TSE::Vector3::Length() const
|
||||
{
|
||||
return std::sqrt(x*x + y*y + z*z);
|
||||
}
|
||||
|
||||
float TSE::Vector3::LengthSqr() const
|
||||
{
|
||||
return x*x + y*y + z*z;
|
||||
}
|
||||
|
||||
bool TSE::Vector3::IsValid() const
|
||||
{
|
||||
return !std::isnan(x) && !std::isnan(y) && !std::isnan(z);
|
||||
}
|
||||
|
||||
void TSE::Vector3::Normalize()
|
||||
{
|
||||
float lensq = LengthSqr();
|
||||
if(lensq <= TSE_EPSILON) return;
|
||||
const float inv = 1.0f / std::sqrt(lensq);
|
||||
x *= inv; y *= inv; z *= inv;
|
||||
}
|
||||
|
||||
void TSE::Vector3::NormalizeSafe(const Vector3 &fallback)
|
||||
{
|
||||
float lensq = LengthSqr();
|
||||
if(lensq <= TSE_EPSILON)
|
||||
{
|
||||
*this = fallback;
|
||||
return;
|
||||
}
|
||||
const float inv = 1.0f / std::sqrt(lensq);
|
||||
x *= inv; y *= inv; z *= inv;
|
||||
if(!IsValid())
|
||||
{
|
||||
*this = fallback;
|
||||
}
|
||||
}
|
||||
|
||||
TSE::string TSE::Vector3::ToString() const
|
||||
{
|
||||
return "(" + std::to_string(x) + "|" + std::to_string(y) + "|" + std::to_string(z) + ")";
|
||||
}
|
||||
|
||||
TSE::Vector2 TSE::Vector3::ToVector2() const
|
||||
{
|
||||
return Vector2(x,y);
|
||||
}
|
||||
|
||||
TSE::Vector4 TSE::Vector3::ToVector4() const
|
||||
{
|
||||
return Vector4(x,y,z,0);
|
||||
}
|
||||
|
||||
float TSE::Vector3::Distance(const Vector3 &a, const Vector3 &b)
|
||||
{
|
||||
return (a - b).Length();
|
||||
}
|
||||
|
||||
float TSE::Vector3::DistanceSqr(const Vector3 &a, const Vector3 &b)
|
||||
{
|
||||
return (a - b).LengthSqr();
|
||||
}
|
||||
|
||||
TSE::Vector3 TSE::Vector3::Normalize(const Vector3 &v)
|
||||
{
|
||||
Vector3 result = v;
|
||||
result.Normalize();
|
||||
return result;
|
||||
}
|
||||
|
||||
TSE::Vector3 TSE::Vector3::NormalizeSafe(const Vector3 &v, const Vector3 &fallback)
|
||||
{
|
||||
Vector3 result = v;
|
||||
result.NormalizeSafe(fallback);
|
||||
return result;
|
||||
}
|
||||
|
||||
TSE::Vector3 TSE::Vector3::Lerp(const Vector3 &a, const Vector3 &b, float t)
|
||||
{
|
||||
return a + (b - a) * t;
|
||||
}
|
||||
|
||||
TSE::Vector3 TSE::Vector3::Berp(const Vector3 &a, const Vector3 &b, const Vector3 &c, float t)
|
||||
{
|
||||
return Lerp(Lerp(a, b, t), Lerp(b, c, t), t);
|
||||
}
|
||||
|
||||
TSE::Vector3 TSE::Vector3::Midpoint(const Vector3 &a, const Vector3 &b)
|
||||
{
|
||||
return (a + b) / 2.0f;
|
||||
}
|
||||
|
||||
float TSE::Vector3::Dot(const Vector3 &a, const Vector3 &b)
|
||||
{
|
||||
return a.x * b.x + a.y * b.y + a.z * b.z;
|
||||
}
|
||||
|
||||
TSE::Vector3 TSE::Vector3::Cross(const Vector3 &a, const Vector3 &b)
|
||||
{
|
||||
return Vector3(
|
||||
a.y * b.z - a.z * b.y,
|
||||
a.z * b.x - a.x * b.z,
|
||||
a.x * b.y - a.y * b.x
|
||||
);
|
||||
}
|
||||
|
||||
TSE::Vector3 TSE::Vector3::operator+(const Vector3 &other) const
|
||||
{
|
||||
return Vector3(x + other.x, y + other.y, z + other.z);
|
||||
}
|
||||
|
||||
TSE::Vector3 TSE::Vector3::operator+=(const Vector3 &other)
|
||||
{
|
||||
*this = *this + other;
|
||||
return *this;
|
||||
}
|
||||
|
||||
TSE::Vector3 TSE::Vector3::operator-(const Vector3 &other) const
|
||||
{
|
||||
return Vector3(x - other.x, y - other.y, z - other.z);
|
||||
}
|
||||
|
||||
TSE::Vector3 TSE::Vector3::operator-=(const Vector3 &other)
|
||||
{
|
||||
*this = *this - other;
|
||||
return *this;
|
||||
}
|
||||
|
||||
TSE::Vector3 TSE::Vector3::operator*(const Vector3 &other) const
|
||||
{
|
||||
return Vector3(x * other.x, y * other.y, z * other.z);
|
||||
}
|
||||
|
||||
TSE::Vector3 TSE::Vector3::operator*=(const Vector3 &other)
|
||||
{
|
||||
*this = *this * other;
|
||||
return *this;
|
||||
}
|
||||
|
||||
TSE::Vector3 TSE::Vector3::operator/(const Vector3 &other) const
|
||||
{
|
||||
return Vector3(x / other.x, y / other.y, z / other.z);
|
||||
}
|
||||
|
||||
TSE::Vector3 TSE::Vector3::operator/=(const Vector3 &other)
|
||||
{
|
||||
*this = *this / other;
|
||||
return *this;
|
||||
}
|
||||
|
||||
TSE::Vector3 TSE::Vector3::operator*(const float other) const
|
||||
{
|
||||
return Vector3(x * other, y * other, z * other);
|
||||
}
|
||||
|
||||
TSE::Vector3 TSE::Vector3::operator*=(const float other)
|
||||
{
|
||||
*this = *this * other;
|
||||
return *this;
|
||||
}
|
||||
|
||||
TSE::Vector3 TSE::Vector3::operator/(const float other) const
|
||||
{
|
||||
return Vector3(x / other, y / other, z / other);
|
||||
}
|
||||
|
||||
TSE::Vector3 TSE::Vector3::operator/=(const float other)
|
||||
{
|
||||
*this = *this / other;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool TSE::Vector3::operator==(const Vector3 &other) const
|
||||
{
|
||||
return x == other.x && y == other.y && z == other.z;
|
||||
}
|
||||
|
||||
bool TSE::Vector3::operator!=(const Vector3 &other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
147
TSE_Math/src/Vector3.hpp
Normal file
147
TSE_Math/src/Vector3.hpp
Normal file
@@ -0,0 +1,147 @@
|
||||
#pragma once
|
||||
|
||||
#include "Types.hpp"
|
||||
|
||||
namespace TSE
|
||||
{
|
||||
class Vector2;
|
||||
class Vector4;
|
||||
|
||||
class Vector3
|
||||
{
|
||||
public:
|
||||
|
||||
#pragma region member
|
||||
float x = 0, y = 0, z = 0;
|
||||
#pragma endregion member
|
||||
|
||||
#pragma region consts
|
||||
static const Vector3 left;
|
||||
static const Vector3 right;
|
||||
static const Vector3 up;
|
||||
static const Vector3 down;
|
||||
static const Vector3 forward;
|
||||
static const Vector3 back;
|
||||
static const Vector3 one;
|
||||
static const Vector3 zero;
|
||||
|
||||
#pragma endregion consts
|
||||
|
||||
#pragma region ctor
|
||||
/// @brief default constructer constructs a Vector3 with (0,0,0)
|
||||
Vector3();
|
||||
/// @brief constructor where you only need to set x and y. z stays 0.
|
||||
/// @param _x x component
|
||||
/// @param _y y component
|
||||
Vector3(float _x, float _y);
|
||||
/// @brief constructor with custom values
|
||||
/// @param _x x component
|
||||
/// @param _y y component
|
||||
/// @param _z z component
|
||||
Vector3(float _x, float _y, float _z);
|
||||
/// @brief copy constructor
|
||||
/// @param other the vector3 to be copied
|
||||
Vector3(const Vector3& other);
|
||||
/// @brief converter constructer. it converts a Vector2 to a vector3 where z gets value 0
|
||||
/// @param other the Vector2 to be converted
|
||||
Vector3(const Vector2& other);
|
||||
/// @brief converter constructer. it converts a Vector4 to a vector3 where w gets disregarded
|
||||
/// @param other the Vector3 to be converted
|
||||
Vector3(const Vector4& other);
|
||||
#pragma endregion ctor
|
||||
|
||||
#pragma region methods
|
||||
/// @brief the length of the vector
|
||||
/// @return the length
|
||||
float Length() const;
|
||||
/// @brief the length² of the vector
|
||||
/// @return the length²
|
||||
float LengthSqr() const;
|
||||
/// @brief checks if the individual components have valid values aka are not nan
|
||||
/// @return are the values valid
|
||||
bool IsValid() const;
|
||||
/// @brief normalizes the Vector3 to have a length of 1
|
||||
void Normalize();
|
||||
/// @brief normalizes the Vector3 to have a length of 1. If the current length of the vector is smaller then epsilon, it gives you the fallback value.
|
||||
/// @param fallback the value to set the vector to if the current length is smaller then epsilon
|
||||
void NormalizeSafe(const Vector3& fallback);
|
||||
/// @brief gives you the vector3 as a string representation. mostly for debugging
|
||||
/// @return the vector3 in a format like (x|y|z)
|
||||
string ToString() const;
|
||||
/// @brief creates a Vector2 with the same values as the Vector3, the y component gets disregarded
|
||||
/// @return the Vector3 as a Vector2
|
||||
Vector2 ToVector2() const;
|
||||
/// @brief creates a Vector4 with the same values as the Vector3, the w component get the value 0
|
||||
/// @return the Vector3 as a Vector4
|
||||
Vector4 ToVector4() const;
|
||||
|
||||
#pragma region static
|
||||
/// @brief gives you the distance between two vectors.
|
||||
/// @param a point 1
|
||||
/// @param b point 2
|
||||
/// @return the distance between point 1 and point 2
|
||||
static float Distance(const Vector3& a, const Vector3& b);
|
||||
/// @brief gives you the distance² between two vectors.
|
||||
/// @param a point 1
|
||||
/// @param b point 2
|
||||
/// @return the distance² between point 1 and point 2
|
||||
static float DistanceSqr(const Vector3& a, const Vector3& b);
|
||||
/// @brief normalizes a copy of the Vector3 to have a length of 1
|
||||
/// @param v the vector to be normaliezed
|
||||
/// @return a normalies copy of the vector
|
||||
static Vector3 Normalize(const Vector3& v);
|
||||
/// @brief normalizes a copy of the Vector3 to have a length of 1. If the current length of the vector is smaller then epsilon, it gives you the fallback value.
|
||||
/// @param fallback the value to set the vector to if the current length is smaller then epsilon
|
||||
/// @param v the vector to be normaliezed
|
||||
/// @return a normalies copy of the vector
|
||||
static Vector3 NormalizeSafe(const Vector3& v, const Vector3& fallback);
|
||||
/// @brief linearly interpolates between two points using t
|
||||
/// @param a point 1
|
||||
/// @param b point 2
|
||||
/// @param t the amoint to interpolate by
|
||||
/// @return the interpolated point
|
||||
static Vector3 Lerp(const Vector3& a, const Vector3& b, float t);
|
||||
/// @brief bezier interpolation using three points using t
|
||||
/// @param a point 1
|
||||
/// @param b controll point
|
||||
/// @param c point 2
|
||||
/// @param t the amoint to interpolate by
|
||||
/// @return the interpolated point
|
||||
static Vector3 Berp(const Vector3& a, const Vector3& b, const Vector3& c, float t);
|
||||
/// @brief gives you the midpoint between two points
|
||||
/// @param a point 1
|
||||
/// @param b point 2
|
||||
/// @return the midpoint
|
||||
static Vector3 Midpoint(const Vector3& a, const Vector3& b);
|
||||
/// @brief gives you the dot product between to vectors
|
||||
/// @param a vector 1
|
||||
/// @param b vector 2
|
||||
/// @return the dot product
|
||||
static float Dot(const Vector3& a, const Vector3& b);
|
||||
/// @brief it gives you the Cross Product
|
||||
/// @param a vector 1
|
||||
/// @param b vector 2
|
||||
/// @return cross product
|
||||
static Vector3 Cross(const Vector3& a, const Vector3& b);
|
||||
#pragma endregion static
|
||||
|
||||
#pragma region operators
|
||||
Vector3 operator+(const Vector3& other) const;
|
||||
Vector3 operator+=(const Vector3& other);
|
||||
Vector3 operator-(const Vector3& other) const;
|
||||
Vector3 operator-=(const Vector3& other);
|
||||
Vector3 operator*(const Vector3& other) const;
|
||||
Vector3 operator*=(const Vector3& other);
|
||||
Vector3 operator/(const Vector3& other) const;
|
||||
Vector3 operator/=(const Vector3& other);
|
||||
Vector3 operator*(const float other) const;
|
||||
Vector3 operator*=(const float other);
|
||||
Vector3 operator/(const float other) const;
|
||||
Vector3 operator/=(const float other);
|
||||
bool operator==(const Vector3& other) const;
|
||||
bool operator!=(const Vector3& other) const;
|
||||
#pragma endregion operators
|
||||
#pragma endregion methods
|
||||
|
||||
};
|
||||
} // namespace TSE
|
||||
162
TSE_Math/src/Vector4.cpp
Normal file
162
TSE_Math/src/Vector4.cpp
Normal file
@@ -0,0 +1,162 @@
|
||||
#include "Vector4.hpp"
|
||||
#include "Vector3.hpp"
|
||||
#include "Vector2.hpp"
|
||||
#include "Color.hpp"
|
||||
#include "Quaternion.hpp"
|
||||
#include <cmath>
|
||||
|
||||
const TSE::Vector4 TSE::Vector4::one = TSE::Vector4(1,1,1,1);
|
||||
const TSE::Vector4 TSE::Vector4::zero = TSE::Vector4(0,0,0,0);
|
||||
|
||||
TSE::Vector4::Vector4() { }
|
||||
|
||||
TSE::Vector4::Vector4(float _x, float _y, float _z, float _w)
|
||||
{
|
||||
x = _x;
|
||||
y = _y;
|
||||
z = _z;
|
||||
w = _w;
|
||||
}
|
||||
|
||||
TSE::Vector4::Vector4(const Vector4 &other)
|
||||
{
|
||||
x = other.x;
|
||||
y = other.y;
|
||||
z = other.z;
|
||||
w = other.w;
|
||||
}
|
||||
|
||||
TSE::Vector4::Vector4(const Vector2 &other)
|
||||
{
|
||||
x = other.x;
|
||||
y = other.y;
|
||||
}
|
||||
|
||||
TSE::Vector4::Vector4(const Vector3 &other)
|
||||
{
|
||||
x = other.x;
|
||||
y = other.y;
|
||||
z = other.z;
|
||||
}
|
||||
|
||||
TSE::Vector4::Vector4(const Color &other)
|
||||
{
|
||||
x = other.r;
|
||||
y = other.g;
|
||||
z = other.b;
|
||||
w = other.a;
|
||||
}
|
||||
|
||||
TSE::Vector4::Vector4(const Quaternion &other)
|
||||
{
|
||||
x = other.x;
|
||||
y = other.y;
|
||||
z = other.z;
|
||||
w = other.w;
|
||||
}
|
||||
|
||||
bool TSE::Vector4::IsValid() const
|
||||
{
|
||||
return !std::isnan(x) && !std::isnan(y) && !std::isnan(z) && !std::isnan(w);
|
||||
}
|
||||
|
||||
TSE::string TSE::Vector4::ToString() const
|
||||
{
|
||||
return "(" + std::to_string(x) + "|" + std::to_string(y) + "|" + std::to_string(z) + "|" + std::to_string(w) + ")";
|
||||
}
|
||||
|
||||
TSE::Vector2 TSE::Vector4::ToVector2() const
|
||||
{
|
||||
return Vector2(x,y);
|
||||
}
|
||||
|
||||
TSE::Vector3 TSE::Vector4::ToVector3() const
|
||||
{
|
||||
return Vector3(x,y,z);
|
||||
}
|
||||
|
||||
TSE::Color TSE::Vector4::ToColor() const
|
||||
{
|
||||
return Color(x,y,z,w);
|
||||
}
|
||||
|
||||
TSE::Quaternion TSE::Vector4::ToQuaternion() const
|
||||
{
|
||||
return Quaternion(x,y,z,w);
|
||||
}
|
||||
|
||||
TSE::Vector4 TSE::Vector4::operator+(const Vector4 &other) const
|
||||
{
|
||||
return Vector4(x + other.x, y + other.y, z + other.z, w + other.w);
|
||||
}
|
||||
|
||||
TSE::Vector4 TSE::Vector4::operator+=(const Vector4 &other)
|
||||
{
|
||||
*this = *this + other;
|
||||
return *this;
|
||||
}
|
||||
|
||||
TSE::Vector4 TSE::Vector4::operator-(const Vector4 &other) const
|
||||
{
|
||||
return Vector4(x - other.x, y - other.y, z - other.z, w - other.w);
|
||||
}
|
||||
|
||||
TSE::Vector4 TSE::Vector4::operator-=(const Vector4 &other)
|
||||
{
|
||||
*this = *this - other;
|
||||
return *this;
|
||||
}
|
||||
|
||||
TSE::Vector4 TSE::Vector4::operator*(const Vector4 &other) const
|
||||
{
|
||||
return Vector4(x * other.x, y * other.y, z * other.z, w * other.w);
|
||||
}
|
||||
|
||||
TSE::Vector4 TSE::Vector4::operator*=(const Vector4 &other)
|
||||
{
|
||||
*this = *this * other;
|
||||
return *this;
|
||||
}
|
||||
|
||||
TSE::Vector4 TSE::Vector4::operator/(const Vector4 &other) const
|
||||
{
|
||||
return Vector4(x / other.x, y / other.y, z / other.z, w / other.w);
|
||||
}
|
||||
|
||||
TSE::Vector4 TSE::Vector4::operator/=(const Vector4 &other)
|
||||
{
|
||||
*this = *this / other;
|
||||
return *this;
|
||||
}
|
||||
|
||||
TSE::Vector4 TSE::Vector4::operator*(const float other) const
|
||||
{
|
||||
return Vector4(x * other, y * other, z * other, w * other);
|
||||
}
|
||||
|
||||
TSE::Vector4 TSE::Vector4::operator*=(const float other)
|
||||
{
|
||||
*this = *this * other;
|
||||
return *this;
|
||||
}
|
||||
|
||||
TSE::Vector4 TSE::Vector4::operator/(const float other) const
|
||||
{
|
||||
return Vector4(x / other, y / other, z / other, w / other);
|
||||
}
|
||||
|
||||
TSE::Vector4 TSE::Vector4::operator/=(const float other)
|
||||
{
|
||||
*this = *this / other;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool TSE::Vector4::operator==(const Vector4 &other) const
|
||||
{
|
||||
return x == other.x && y == other.y && z == other.z && w == other.w;
|
||||
}
|
||||
|
||||
bool TSE::Vector4::operator!=(const Vector4 &other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
88
TSE_Math/src/Vector4.hpp
Normal file
88
TSE_Math/src/Vector4.hpp
Normal file
@@ -0,0 +1,88 @@
|
||||
#pragma once
|
||||
|
||||
#include "Types.hpp"
|
||||
|
||||
namespace TSE
|
||||
{
|
||||
class Vector2;
|
||||
class Vector3;
|
||||
class Color;
|
||||
class Quaternion;
|
||||
|
||||
class Vector4
|
||||
{
|
||||
public:
|
||||
#pragma region members
|
||||
float x = 0, y = 0, z = 0, w = 0;
|
||||
#pragma endregion members
|
||||
|
||||
#pragma region consts
|
||||
static const Vector4 one;
|
||||
static const Vector4 zero;
|
||||
#pragma endregion consts
|
||||
|
||||
#pragma region ctor
|
||||
/// @brief default constructer constructs a Vector4 with (0,0,0,0)
|
||||
Vector4();
|
||||
/// @brief constructor with custom values
|
||||
/// @param _x x component
|
||||
/// @param _y y component
|
||||
/// @param _z z component
|
||||
/// @param _w w component
|
||||
Vector4(float _x, float _y, float _z, float _w);
|
||||
/// @brief copy constructor
|
||||
/// @param other the vector4 to be copied
|
||||
Vector4(const Vector4& other);
|
||||
/// @brief converter constructer. it converts a Vector2 to a vector4 where z and w gets value 0
|
||||
/// @param other the Vector2 to be converted
|
||||
Vector4(const Vector2& other);
|
||||
/// @brief converter constructer. it converts a Vector3 to a vector4 where w gets value 0
|
||||
/// @param other the Vector3 to be converted
|
||||
Vector4(const Vector3& other);
|
||||
/// @brief converter constructer. it converts a Color to a vector4
|
||||
/// @param other the Color to be converted
|
||||
Vector4(const Color& other);
|
||||
/// @brief converter constructer. it converts a Quaternion to a vector4
|
||||
/// @param other the Quaternion to be converted
|
||||
Vector4(const Quaternion& other);
|
||||
#pragma endregion ctor
|
||||
|
||||
#pragma region methods
|
||||
/// @brief checks if the individual components have valid values aka are not nan
|
||||
/// @return are the values valid
|
||||
bool IsValid() const;
|
||||
/// @brief gives you the vector4 as a string representation. mostly for debugging
|
||||
/// @return the vector4 in a format like (x|y|z|w)
|
||||
string ToString() const;
|
||||
/// @brief creates a Vector2 with the same values as the Vector4, the w and y component gets disregarded
|
||||
/// @return the Vector4 as a Vector2
|
||||
Vector2 ToVector2() const;
|
||||
/// @brief creates a Vector3 with the same values as the Vector4, the w component gets disregarded
|
||||
/// @return the Vector4 as a Vector3
|
||||
Vector3 ToVector3() const;
|
||||
/// @brief creates a Color with the same values as the Vector4
|
||||
/// @return the Vector4 as a Color
|
||||
Color ToColor() const;
|
||||
/// @brief creates a Quaternion with the same values as the Vector4
|
||||
/// @return the Vector4 as a Quaternion
|
||||
Quaternion ToQuaternion() const;
|
||||
|
||||
#pragma region operators
|
||||
Vector4 operator+(const Vector4& other) const;
|
||||
Vector4 operator+=(const Vector4& other);
|
||||
Vector4 operator-(const Vector4& other) const;
|
||||
Vector4 operator-=(const Vector4& other);
|
||||
Vector4 operator*(const Vector4& other) const;
|
||||
Vector4 operator*=(const Vector4& other);
|
||||
Vector4 operator/(const Vector4& other) const;
|
||||
Vector4 operator/=(const Vector4& other);
|
||||
Vector4 operator*(const float other) const;
|
||||
Vector4 operator*=(const float other);
|
||||
Vector4 operator/(const float other) const;
|
||||
Vector4 operator/=(const float other);
|
||||
bool operator==(const Vector4& other) const;
|
||||
bool operator!=(const Vector4& other) const;
|
||||
#pragma endregion operators
|
||||
#pragma endregion methods
|
||||
};
|
||||
} // namespace TSE
|
||||
Reference in New Issue
Block a user