Compare commits

..

12 Commits

17 changed files with 3941 additions and 3426 deletions

View File

@@ -21,7 +21,9 @@ clang-analyzer-*,
-modernize-avoid-c-arrays, -modernize-avoid-c-arrays,
-cppcoreguidelines-pro-bounds-array-to-pointer-decay, -cppcoreguidelines-pro-bounds-array-to-pointer-decay,
-readability-named-parameter, -readability-named-parameter,
-cert-env33-c -cert-env33-c,
-readability-identifier-length,
-cppcoreguidelines-pro-type-union-access
' '

32
.vscode/launch.json vendored
View File

@@ -1,32 +0,0 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Debug MathTestFPU (gdb)",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/bin/1.0.0/Debug/MathTestFPU/MathTestFPU",
"args": [],
"stopAtEntry": false,
"cwd": "${fileDirname}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"description": "Set Disassembly Flavor to Intel",
"text": "-gdb-set disassembly-flavor intel",
"ignoreFailures": true
}
]
}
]
}

152
.vscode/settings.json vendored
View File

@@ -1,152 +0,0 @@
{
"C_Cpp.formatting": "clangFormat",
"C_Cpp.loggingLevel": "Error",
"C_Cpp.default.cppStandard": "c++20",
"C_Cpp.default.includePath": [
"${workspaceFolder}/Engine/Source/Runtime/",
"${workspaceFolder}/Engine/Source/ThirdParty/"
],
"C_Cpp.default.browse.path": [
"${workspaceFolder}/Engine/Source/Runtime",
"${workspaceFolder}/Engine/Source/ThirdParty"
],
"C_Cpp.default.browse.databaseFilename": "${workspaceFolder}/.vscode/browse.vc.db",
"files.associations": {
"cstdint": "cpp",
"chrono": "cpp",
"string": "cpp",
"cctype": "cpp",
"clocale": "cpp",
"cmath": "cpp",
"cstdarg": "cpp",
"cstddef": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"cstring": "cpp",
"ctime": "cpp",
"cwchar": "cpp",
"cwctype": "cpp",
"any": "cpp",
"array": "cpp",
"atomic": "cpp",
"bit": "cpp",
"*.tcc": "cpp",
"bitset": "cpp",
"charconv": "cpp",
"cinttypes": "cpp",
"codecvt": "cpp",
"compare": "cpp",
"complex": "cpp",
"concepts": "cpp",
"condition_variable": "cpp",
"deque": "cpp",
"forward_list": "cpp",
"list": "cpp",
"map": "cpp",
"set": "cpp",
"unordered_map": "cpp",
"unordered_set": "cpp",
"vector": "cpp",
"exception": "cpp",
"expected": "cpp",
"algorithm": "cpp",
"functional": "cpp",
"iterator": "cpp",
"memory": "cpp",
"memory_resource": "cpp",
"numeric": "cpp",
"optional": "cpp",
"random": "cpp",
"ratio": "cpp",
"regex": "cpp",
"source_location": "cpp",
"string_view": "cpp",
"system_error": "cpp",
"tuple": "cpp",
"type_traits": "cpp",
"utility": "cpp",
"hash_map": "cpp",
"hash_set": "cpp",
"format": "cpp",
"fstream": "cpp",
"future": "cpp",
"initializer_list": "cpp",
"iomanip": "cpp",
"iosfwd": "cpp",
"iostream": "cpp",
"istream": "cpp",
"limits": "cpp",
"mutex": "cpp",
"new": "cpp",
"numbers": "cpp",
"ostream": "cpp",
"semaphore": "cpp",
"shared_mutex": "cpp",
"span": "cpp",
"sstream": "cpp",
"stdexcept": "cpp",
"stdfloat": "cpp",
"stop_token": "cpp",
"streambuf": "cpp",
"text_encoding": "cpp",
"thread": "cpp",
"cfenv": "cpp",
"typeindex": "cpp",
"typeinfo": "cpp",
"valarray": "cpp",
"variant": "cpp"
},
"C_Cpp.default.defines": [
"P_LINUX_BUILD",
"__SSE__",
],
"C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools",
"editor.tokenColorCustomizations": {
"[*Light*]": {
"textMateRules": [
{
"scope": "ref.matchtext",
"settings": {
"foreground": "#000"
}
}
]
},
"[*Dark*]": {
"textMateRules": [
{
"scope": "ref.matchtext",
"settings": {
"foreground": "#fff"
}
}
]
},
"textMateRules": [
{
"scope": "googletest.failed",
"settings": {
"foreground": "#f00"
}
},
{
"scope": "googletest.passed",
"settings": {
"foreground": "#0f0"
}
},
{
"scope": "googletest.run",
"settings": {
"foreground": "#0f0"
}
}
]
},
"gtest-adapter.debugConfig": [
"Debug MathTestFPU (gdb)"
],
"gtest-adapter.supportLocation": true,
"premake.version": "Premake 5.0-beta5",
}

28
.vscode/tasks.json vendored
View File

@@ -1,28 +0,0 @@
{
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: g++ build active file",
"command": "/sbin/g++",
"args": [
"-fdiagnostics-color=always",
"-g",
"${file}",
"-o",
"${fileDirname}/${fileBasenameNoExtension}"
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "Task generated by Debugger."
}
],
"version": "2.0.0"
}

View File

@@ -4,92 +4,87 @@
// ============================================= // // ============================================= //
// Turn os specific types into global types. // // Turn os specific types into global types. //
// ============================================= // // ============================================= //
namespace Phanes::Core::Types namespace Phanes::Core::Types
{ {
// Specific types size // Specific types size
// //
// 8-Bit integer // 8-Bit integer
typedef int8_t int8; using int8 = int8_t;
// 16-Bit integer // 16-Bit integer
typedef int16_t int16; using int16 = int16_t;
// 32-Bit integer // 32-Bit integer
typedef int32_t int32; using int32 = int32_t;
// 64-Bit integer // 64-Bit integer
typedef int64_t int64; using int64 = int64_t;
// 8-Bit unsigned integer // 8-Bit unsigned integer
typedef uint8_t uint8; using uint8 = uint8_t;
// 16-Bit unsigned integer // 16-Bit unsigned integer
typedef uint16_t uint16; using uint16 = uint16_t;
// 32-Bit unsigned integer // 32-Bit unsigned integer
typedef uint32_t uint32; using uint32 = uint32_t;
// 64-Bit unsigned integer // 64-Bit unsigned integer
typedef uint64_t uint64; using uint64 = uint64_t;
// At least N bit types
//
// At least 8-Bit integer
using lint8 = int_least8_t;
// At least 16-Bit integer
using lint16 = int_least16_t;
// At least N bit types // At least 32-Bit integer
// using lint32 = int_least32_t;
// At least 8-Bit integer
typedef int_least8_t lint8;
// At least 16-Bit integer // At least 64-Bit integer
typedef int_least16_t lint16; using lint64 = int_least64_t;
// At least 32-Bit integer // At least 8-Bit integer
typedef int_least32_t lint32; using ulint8 = uint_least8_t;
// At least 64-Bit integer // At least 16-Bit integer
typedef int_least64_t lint64; using ulint16 = uint_least16_t;
// At least 8-Bit integer // At least 32-Bit integer
typedef uint_least8_t ulint8; using ulint32 = uint_least32_t;
// At least 16-Bit integer // At least 64-Bit integer
typedef uint_least16_t ulint16; using ulint64 = uint_least64_t;
// At least 32-Bit integer // Fast N bit types
typedef uint_least32_t ulint32; //
// Fast 8-bit integer
using fint8 = int_fast8_t;
// At least 64-Bit integer // At least 16-Bit integer
typedef uint_least64_t ulint64; using fint16 = int_fast16_t;
// At least 32-Bit integer
using fint32 = int_fast32_t;
// At least 64-Bit integer
using fint64 = int_fast64_t;
// Fast N bit types // At least 8-Bit integer
// using ufint8 = uint_fast8_t;
// Fast 8-bit integer
typedef int_fast8_t fint8;
// At least 16-Bit integer // At least 16-Bit integer
typedef int_fast16_t fint16; using ufint16 = uint_fast16_t;
// At least 32-Bit integer // At least 32-Bit integer
typedef int_fast32_t fint32; using ufint32 = uint_fast32_t;
// At least 64-Bit integer // At least 64-Bit integer
typedef int_fast64_t fint64; using ufint64 = uint_fast64_t;
// At least 8-Bit integer } // namespace Phanes::Core::Types
typedef uint_fast8_t ufint8;
// At least 16-Bit integer
typedef uint_fast16_t ufint16;
// At least 32-Bit integer
typedef uint_fast32_t ufint32;
// At least 64-Bit integer
typedef uint_fast64_t ufint64;
}

View File

@@ -1,201 +1,238 @@
#pragma once #pragma once
#ifdef P_BUILD_LIB #ifdef P_BUILD_LIB
#include "PhanesEnginePCH.h" # include "PhanesEnginePCH.h"
#else #else
#include <vector> # include <vector>
#endif #endif
#ifndef MATH_FWD_H #ifndef MATH_FWD_H
#define MATH_FWD_H # define MATH_FWD_H
#include "Core/Math/Boilerplate.h" # include "Core/Math/Boilerplate.h"
#include "Core/Math/SIMD/PhanesSIMDTypes.h" # include "Core/Math/SIMD/PhanesSIMDTypes.h"
/** /**
* Includes forward declarations, as well as certain useful typedefs. * Includes forward declarations, as well as certain useful usings.
* *
* @ref OSAL/PlatformTypes.h * @ref OSAL/PlatformTypes.h
*/ */
namespace Phanes::Core::Math
{
namespace Phanes::Core::Math { /**
/**
* Template forward declarations. * Template forward declarations.
*/ */
template<RealType T> struct TColor; template <RealType T>
template<RealType T> struct TLinearColor; struct TColor;
template<RealType T> struct TLine;
template<RealType T> struct TQuaternion;
template<RealType T> struct TTransform;
template<RealType T> struct TPoint2;
template<RealType T> struct TPoint3;
template<RealType T> struct TPoint4;
template<IntType T> struct TIntPoint2;
template<IntType T> struct TIntPoint3;
template<IntType T> struct TIntPoint4;
template<RealType T> struct TMatrix2;
template<RealType T, bool S> struct TMatrix3;
template<RealType T, bool S> struct TMatrix4;
template<RealType T, bool S> struct TVector2;
template<RealType T, bool S> struct TVector3;
template<RealType T, bool S> struct TVector4;
template<IntType T, bool S> struct TIntVector2;
template<IntType T, bool S> struct TIntVector3;
template<IntType T, bool S> struct TIntVector4;
template<RealType T, bool S> struct TPlane;
template<RealType T, bool S> struct TRay;
/** template <RealType T>
struct TLinearColor;
template <RealType T>
struct TLine;
template <RealType T>
struct TTransform;
template <RealType T>
struct TPoint2;
template <RealType T>
struct TPoint3;
template <RealType T>
struct TPoint4;
template <IntType T>
struct TIntPoint2;
template <IntType T>
struct TIntPoint3;
template <IntType T>
struct TIntPoint4;
template <RealType T>
struct TMatrix2;
template <RealType T, bool S>
struct TQuaternion;
template <RealType T, bool S>
struct TMatrix3;
template <RealType T, bool S>
struct TMatrix4;
template <RealType T, bool S>
struct TVector2;
template <RealType T, bool S>
struct TVector3;
template <RealType T, bool S>
struct TVector4;
template <IntType T, bool S>
struct TIntVector2;
template <IntType T, bool S>
struct TIntVector3;
template <IntType T, bool S>
struct TIntVector4;
template <RealType T, bool S>
struct TPlane;
template <RealType T, bool S>
struct TRay;
/**
* Specific instantiation of forward declarations. * Specific instantiation of forward declarations.
*/ */
// TPoint2 // TPoint2
typedef TPoint2<float> Point2; using Point2 = TPoint2<float>;
typedef TPoint2<float> Point2f; using Point2f = TPoint2<float>;
typedef TPoint2<double> Point2d; using Point2d = TPoint2<double>;
// TPoint3 // TPoint3
typedef TPoint3<float> Point3; using Point3 = TPoint3<float>;
typedef TPoint3<float> Point3f; using Point3f = TPoint3<float>;
typedef TPoint3<double> Point3d; using Point3d = TPoint3<double>;
// TPoint4 // TPoint4
typedef TPoint4<float> Point4; using Point4 = TPoint4<float>;
typedef TPoint4<float> Point4f; using Point4f = TPoint4<float>;
typedef TPoint4<double> Point4d; using Point4d = TPoint4<double>;
// TIntPoint2
// TIntPoint2 using IntPoint2 = TIntPoint2<int>;
using IntPoint2i = TIntPoint2<int>;
using IntPoint2l = TIntPoint2<long>;
typedef TIntPoint2<int> IntPoint2; // TIntPoint3
typedef TIntPoint2<int> IntPoint2i;
typedef TIntPoint2<long> IntPoint2l;
// TIntPoint3 using IntPoint3 = TIntPoint3<int>;
using IntPoint3i = TIntPoint3<int>;
using IntPoint3l = TIntPoint3<long>;
typedef TIntPoint3<int> IntPoint3; // TIntPoint4
typedef TIntPoint3<int> IntPoint3i;
typedef TIntPoint3<long> IntPoint3l;
// TIntPoint4 using IntPoint4 = TIntPoint4<int>;
using IntPoint4i = TIntPoint4<int>;
using IntPoint4l = TIntPoint4<long>;
typedef TIntPoint4<int> IntPoint4; // IntVetor2
typedef TIntPoint4<int> IntPoint4i;
typedef TIntPoint4<long> IntPoint4l;
// IntVetor2 using IntVector2 = TIntVector2<int, false>;
using Vector2i = TIntVector2<int, false>;
using LongVector2 = TIntVector2<long, false>;
using Vector2l = TIntVector2<long, false>;
typedef TIntVector2<int, false> IntVector2; // IntVetor3
typedef TIntVector2<int, false> Vector2i;
typedef TIntVector2<long, false> LongVector2;
typedef TIntVector2<long, false> Vector2l;
// IntVetor3 using IntVector3 = TIntVector3<int, false>;
using Vector3i = TIntVector3<int, false>;
using LongVector3 = TIntVector3<long, false>;
using Vector3l = TIntVector3<long, false>;
typedef TIntVector3<int, false> IntVector3; // IntVetor4
typedef TIntVector3<int, false> Vector3i;
typedef TIntVector3<long, false> LongVector3;
typedef TIntVector3<long, false> Vector3l;
using IntVector4 = TIntVector4<int, false>;
using Vector4i = TIntVector4<int, false>;
using LongVector4 = TIntVector4<long, false>;
using Vector4l = TIntVector4<long, false>;
// IntVetor4 // Vector2
typedef TIntVector4<int, false> IntVector4; using Vector2 = TVector2<float, false>;
typedef TIntVector4<int, false> Vector4i; using Vector2f = TVector2<float, false>;
typedef TIntVector4<long, false> LongVector4; using Vector2d = TVector2<double, false>;
typedef TIntVector4<long, false> Vector4l;
// Vector2 using Vector2Regf64 = TVector2<double, SIMD::use_simd<double, 2, true>::value>;
using Vector2Reg = TVector2<double, SIMD::use_simd<double, 2, true>::value>;
using Vector2Regd = TVector2<double, SIMD::use_simd<double, 2, true>::value>;
typedef TVector2<float, false> Vector2; // Vector3
typedef TVector2<float, false> Vector2f;
typedef TVector2<double, false> Vector2d;
typedef TVector2<double, SIMD::use_simd<double, 2, true>::value> Vector2Regf64; using Vector3 = TVector3<float, false>;
typedef TVector2<double, SIMD::use_simd<double, 2, true>::value> Vector2Reg; using Vector3f = TVector3<float, false>;
typedef TVector2<double, SIMD::use_simd<double, 2, true>::value> Vector2Regd; using Vector3d = TVector3<double, false>;
using Vector3Reg = TVector3<float, SIMD::use_simd<float, 3, true>::value>;
using Vector3Regf32 = TVector3<float, SIMD::use_simd<float, 3, true>::value>;
using Vector3Regd = TVector3<double, SIMD::use_simd<double, 3, true>::value>;
using Vector3Regf64 = TVector3<double, SIMD::use_simd<double, 3, true>::value>;
// Vector3 // Vector4
typedef TVector3<float, false> Vector3; using Vector4 = TVector4<float, false>;
typedef TVector3<float, false> Vector3f; using Vector4f = TVector4<float, false>;
typedef TVector3<double, false> Vector3d; using Vector4d = TVector4<double, false>;
typedef TVector3<float, SIMD::use_simd<float, 3, true>::value> Vector3Reg; using Vector4Reg = TVector4<float, SIMD::use_simd<float, 4, true>::value>;
typedef TVector3<float, SIMD::use_simd<float, 3, true>::value> Vector3Regf32; using Vector4Regf32 = TVector4<float, SIMD::use_simd<float, 4, true>::value>;
typedef TVector3<double, SIMD::use_simd<double, 3, true>::value> Vector3Regd; using Vector4Regd = TVector4<double, SIMD::use_simd<double, 4, true>::value>;
typedef TVector3<double, SIMD::use_simd<double, 3, true>::value> Vector3Regf64; using Vector4Regf64 = TVector4<double, SIMD::use_simd<double, 4, true>::value>;
// Matrix2
// Vector4 using Matrix2 = TMatrix2<float>;
using Matrix2f = TMatrix2<float>;
using Matrix2d = TMatrix2<double>;
typedef TVector4<float, false> Vector4; // Matrix3
typedef TVector4<float, false> Vector4f;
typedef TVector4<double, false> Vector4d;
typedef TVector4<float, SIMD::use_simd<float, 4, true>::value> Vector4Reg; using Matrix3 = TMatrix3<float, false>;
typedef TVector4<float, SIMD::use_simd<float, 4, true>::value> Vector4Regf32; using Matrix3f = TMatrix3<float, false>;
typedef TVector4<double, SIMD::use_simd<double, 4, true>::value> Vector4Regd; using Matrix3d = TMatrix3<double, false>;
typedef TVector4<double, SIMD::use_simd<double, 4, true>::value> Vector4Regf64;
// Matrix2
typedef TMatrix2<float> Matrix2;
typedef TMatrix2<float> Matrix2f;
typedef TMatrix2<double> Matrix2d;
// Matrix3 using Matrix3Reg = TMatrix3<float, SIMD::use_simd<float, 3, true>::value>;
using Matrix3Regf = TMatrix3<float, SIMD::use_simd<float, 3, true>::value>;
using Matrix3Regd = TMatrix3<double, SIMD::use_simd<double, 3, true>::value>;
using Matrix3Regf64 = TMatrix3<double, SIMD::use_simd<double, 3, true>::value>;
typedef TMatrix3<float, false> Matrix3; // Matrix4
typedef TMatrix3<float, false> Matrix3f;
typedef TMatrix3<double, false> Matrix3d;
typedef TMatrix3<float, SIMD::use_simd<float, 3, true>::value> Matrix3Reg; using Matrix4 = TMatrix4<float, false>;
typedef TMatrix3<float, SIMD::use_simd<float, 3, true>::value> Matrix3Regf; using Matrix4f = TMatrix4<float, false>;
typedef TMatrix3<double, SIMD::use_simd<double, 3, true>::value> Matrix3Regd; using Matrix4d = TMatrix4<double, false>;
typedef TMatrix3<double, SIMD::use_simd<double, 3, true>::value> Matrix3Regf64;
// Matrix4 using Matrix4Reg = TMatrix3<float, SIMD::use_simd<float, 4, true>::value>;
using Matrix4Regf = TMatrix3<float, SIMD::use_simd<float, 4, true>::value>;
using Matrix4Regd = TMatrix3<double, SIMD::use_simd<double, 4, true>::value>;
using Matrix4Regf64 = TMatrix3<double, SIMD::use_simd<double, 4, true>::value>;
typedef TMatrix4<float, false> Matrix4; // TPlane
typedef TMatrix4<float, false> Matrix4f;
typedef TMatrix4<double, false> Matrix4d;
typedef TMatrix3<float, SIMD::use_simd<float, 4, true>::value> Matrix4Reg; using Plane = TPlane<float, false>;
typedef TMatrix3<float, SIMD::use_simd<float, 4, true>::value> Matrix4Regf; using Planef = TPlane<float, false>;
typedef TMatrix3<double, SIMD::use_simd<double, 4, true>::value> Matrix4Regd; using Planed = TPlane<double, false>;
typedef TMatrix3<double, SIMD::use_simd<double, 4, true>::value> Matrix4Regf64;
using PlaneReg = TPlane<float, SIMD::use_simd<float, 4, true>::value>;
using PlaneRegd = TPlane<float, SIMD::use_simd<double, 4, true>::value>;
} // namespace Phanes::Core::Math
// TPlane
typedef TPlane<float, false> Plane;
typedef TPlane<float, false> Planef;
typedef TPlane<double, false> Planed;
typedef TPlane<float, SIMD::use_simd<float, 4, true>::value> PlaneReg;
typedef TPlane<float, SIMD::use_simd<double, 4, true>::value> PlaneRegd;
} // Phanes::Core::Math::coretypes
namespace Phanes::Core::Math::Internal namespace Phanes::Core::Math::Internal
{ {
// Internal types // Internal types
template <typename T, unsigned int D> struct AVector; template <typename T, unsigned int D>
struct AVector;
template <typename T, unsigned int n, unsigned int> struct AMatrix; template <typename T, unsigned int n, unsigned int>
} struct AMatrix;
} // namespace Phanes::Core::Math::Internal
#endif // !MATH_FWD_H
#endif // !MATH_FWD_H

View File

@@ -4,8 +4,7 @@
// ============================================= // // ============================================= //
// Turn os specific types into global types. // // Turn os specific types into global types. //
// ============================================= // // ============================================= //
// TODO: include int128 // TODO: include int128
@@ -14,99 +13,93 @@ namespace Phanes::Core::Types
#ifdef P_WIN_BUILD #ifdef P_WIN_BUILD
// MSVC specific types // MSVC specific types
typedef _FLOAT128 float128; using float128 = _FLOAT128;
#elif defined(P_LINUX_BUILD) #elif defined(P_LINUX_BUILD)
// Linux specific types // Linux specific types
typedef __float128 float128; using float128 = __float128;
#endif #endif
// Specific types size
//
// 8-Bit integer
using int8 = int8_t;
// 16-Bit integer
using int16 = int16_t;
// Specific types size // 32-Bit integer
// using int32 = int32_t;
// 8-Bit integer
typedef int8_t int8;
// 16-Bit integer // 64-Bit integer
typedef int16_t int16; using int64 = int64_t;
// 32-Bit integer // 8-Bit unsigned integer
typedef int32_t int32; using uint8 = uint8_t;
// 64-Bit integer // 16-Bit unsigned integer
typedef int64_t int64; using uint16 = uint16_t;
// 8-Bit unsigned integer // 32-Bit unsigned integer
typedef uint8_t uint8; using uint32 = uint32_t;
// 16-Bit unsigned integer // 64-Bit unsigned integer
typedef uint16_t uint16; using uint64 = uint64_t;
// 32-Bit unsigned integer // At least N bit types
typedef uint32_t uint32; //
// At least 8-Bit integer
using lint8 = int_least8_t;
// 64-Bit unsigned integer // At least 16-Bit integer
typedef uint64_t uint64; using lint16 = int_least16_t;
// At least 32-Bit integer
using lint32 = int_least32_t;
// At least 64-Bit integer
using lint64 = int_least64_t;
// At least N bit types // At least 8-Bit integer
// using ulint8 = uint_least8_t;
// At least 8-Bit integer
typedef int_least8_t lint8;
// At least 16-Bit integer // At least 16-Bit integer
typedef int_least16_t lint16; using ulint16 = uint_least16_t;
// At least 32-Bit integer // At least 32-Bit integer
typedef int_least32_t lint32; using ulint32 = uint_least32_t;
// At least 64-Bit integer // At least 64-Bit integer
typedef int_least64_t lint64; using ulint64 = uint_least64_t;
// At least 8-Bit integer // Fast N bit types
typedef uint_least8_t ulint8; //
// Fast 8-bit integer
using fint8 = int_fast8_t;
// At least 16-Bit integer // At least 16-Bit integer
typedef uint_least16_t ulint16; using fint16 = int_fast16_t;
// At least 32-Bit integer // At least 32-Bit integer
typedef uint_least32_t ulint32; using fint32 = int_fast32_t;
// At least 64-Bit integer // At least 64-Bit integer
typedef uint_least64_t ulint64; using fint64 = int_fast64_t;
// At least 8-Bit integer
using ufint8 = uint_fast8_t;
// At least 16-Bit integer
using ufint16 = uint_fast16_t;
// Fast N bit types // At least 32-Bit integer
// using ufint32 = uint_fast32_t;
// Fast 8-bit integer
typedef int_fast8_t fint8;
// At least 16-Bit integer // At least 64-Bit integer
typedef int_fast16_t fint16; using ufint64 = uint_fast64_t;
// At least 32-Bit integer } // namespace Phanes::Core::Types
typedef int_fast32_t fint32;
// At least 64-Bit integer
typedef int_fast64_t fint64;
// At least 8-Bit integer
typedef uint_fast8_t ufint8;
// At least 16-Bit integer
typedef uint_fast16_t ufint16;
// At least 32-Bit integer
typedef uint_fast32_t ufint32;
// At least 64-Bit integer
typedef uint_fast64_t ufint64;
}

View File

@@ -7,352 +7,345 @@
#include "Core/Math/Vector2.hpp" #include "Core/Math/Vector2.hpp"
#ifndef MATRIX2_H #ifndef MATRIX2_H
#define MATRIX2_H # define MATRIX2_H
namespace Phanes::Core::Math { namespace Phanes::Core::Math
{
// 2x2 Matrix defined in column-major order.
// Accessed by M[Row][Col].
template<RealType T> // 2x2 Matrix defined in column-major order.
struct TMatrix2 // Accessed by M[Col][Row].
{
public:
union template <RealType T>
{ struct TMatrix2
struct {
{ public:
/// <summary> union
/// Column one. {
/// </summary> struct
TVector2<T, false> c0; {
/// <summary>
/// Column one.
/// </summary>
TVector2<T, false> c0;
/// <summary> /// <summary>
/// Column two /// Column two
/// </summary> /// </summary>
TVector2<T, false> c1; TVector2<T, false> c1;
}; };
T data[2][2]; T data[2][2];
}; };
public: public:
TMatrix2() = default;
TMatrix2() = default; /**
/**
* Copy constructor. * Copy constructor.
*/ */
TMatrix2(const TMatrix2<T>& m1) TMatrix2(const TMatrix2<T>& m1)
{ {
this->c0 = m1.c0; this->c0 = m1.c0;
this->c1 = m1.c1; this->c1 = m1.c1;
} }
/** /**
* Construct Matrix from 2d array. * Construct Matrix from 2d array.
* *
* @param(fields) 2D Array with column major order. * @param(fields) 2D Array with column major order.
*/ */
TMatrix2(T fields[2][2]) TMatrix2(T fields[2][2])
{ {
this->data[0][0] = fields[0][0]; this->data[1][0] = fields[1][0]; this->data[0][0] = fields[0][0];
this->data[0][1] = fields[0][1]; this->data[1][1] = fields[1][1]; this->data[1][0] = fields[1][0];
} this->data[0][1] = fields[0][1];
this->data[1][1] = fields[1][1];
}
/** /**
* Construct Matrix from parameters. * Construct Matrix from parameters.
* *
* @param(n00) M[0][0] * @param(n00) M[0][0]
* @param(n10) M[1][0] * @param(n01) M[1][0]
* @param(n01) M[0][1] * @param(n10) M[0][1]
* @param(n11) M[1][1] * @param(n11) M[1][1]
* *
* @note nXY = n[Row][Col] * @note nXY = n[Col][Row]
*/ */
TMatrix2(T n00, T n01, T n10, T n11) TMatrix2(T n00, T n01, T n10, T n11)
{ {
this->data[0][0] = n00; this->data[1][0] = n01; this->data[0][0] = n00;
this->data[0][1] = n10; this->data[1][1] = n11; this->data[1][0] = n01;
} this->data[0][1] = n10;
this->data[1][1] = n11;
}
/** /**
* Construct Matrix from two 2d vector columns. * Construct Matrix from two 2d vector columns.
* *
* @param(v1) Column zero * @param(v1) Column zero
* @param(v2) Column one * @param(v2) Column one
*/ */
TMatrix2(const TVector2<T, false>& v1, const TVector2<T, false>& v2) TMatrix2(const TVector2<T, false>& v1, const TVector2<T, false>& v2)
{ {
this->c0 = v1; this->c0 = v1;
this->c1 = v2; this->c1 = v2;
} }
public: public:
T& operator()(int n, int m)
{
return this->data[m][n];
}
T& operator() (int n, int m) T operator()(int n, int m) const
{ {
return this->data[m][n]; return this->data[m][n];
} }
T operator() (int n, int m) const TVector2<T, false>& operator[](int m)
{ {
return this->data[m][n]; switch(m)
} {
case 0:
return this->c0;
case 1:
return this->c1;
}
TVector2<T, false>& operator[] (int m) throw std::invalid_argument("m is outside valid range.");
{ }
switch (m)
{
case 0:
return this->c0;
case 1:
return this->c1;
}
throw std::invalid_argument("m is outside valid range."); TVector2<T, false> operator[](int m) const
} {
switch(m)
{
case 0:
return this->c0;
case 1:
return this->c1;
}
TVector2<T, false> operator[] (int m) const throw std::invalid_argument("m is outside valid range.");
{ }
switch (m) };
{
case 0:
return this->c0;
case 1:
return this->c1;
}
throw std::invalid_argument("m is outside valid range."); // ====================== //
} // TMatrix2 operator //
// ====================== //
}; template <RealType T>
TMatrix2<T>& operator+=(TMatrix2<T>& m1, T s)
{
m1(0, 0) += s;
m1(0, 1) += s;
m1(1, 0) += s;
m1(1, 1) += s;
// ====================== // return m1;
// TMatrix2 operator // }
// ====================== //
template<RealType T>
TMatrix2<T>& operator+= (TMatrix2<T>& m1, T s)
{
m1(0, 0) += s;
m1(0, 1) += s;
m1(1, 0) += s;
m1(1, 1) += s;
return m1; template <RealType T>
} TMatrix2<T>& operator+=(TMatrix2<T>& m1, const TMatrix2<T>& m2)
{
m1(0, 0) += m2(0, 0);
m1(0, 1) += m2(0, 1);
m1(1, 0) += m2(1, 0);
m1(1, 1) += m2(1, 1);
template<RealType T> return m1;
TMatrix2<T>& operator+= (TMatrix2<T>& m1, const TMatrix2<T>& m2) }
{
m1(0, 0) += m2(0, 0);
m1(0, 1) += m2(0, 1);
m1(1, 0) += m2(1, 0);
m1(1, 1) += m2(1, 1);
return m1; template <RealType T>
} TMatrix2<T>& operator-=(TMatrix2<T>& m1, T s)
{
template<RealType T> m1(0, 0) -= s;
TMatrix2<T>& operator-= (TMatrix2<T>& m1, T s) m1(0, 1) -= s;
{ m1(1, 0) -= s;
m1(0, 0) -= s; m1(1, 1) -= s;
m1(0, 1) -= s;
m1(1, 0) -= s;
m1(1, 1) -= s;
return m1; return m1;
} }
template<RealType T>
TMatrix2<T>& operator-= (TMatrix2<T>& m1, const TMatrix2<T>& m2)
{
m1(0, 0) -= m2(0, 0);
m1(0, 1) -= m2(0, 1);
m1(1, 0) -= m2(1, 0);
m1(1, 1) -= m2(1, 1);
return m1; template <RealType T>
} TMatrix2<T>& operator-=(TMatrix2<T>& m1, const TMatrix2<T>& m2)
{
template<RealType T> m1(0, 0) -= m2(0, 0);
TMatrix2<T>& operator*= (TMatrix2<T>& m1, T s) m1(0, 1) -= m2(0, 1);
{ m1(1, 0) -= m2(1, 0);
m1.data[0][0] *= s; m1(1, 1) -= m2(1, 1);
m1.data[0][1] *= s;
m1.data[1][0] *= s;
m1.data[1][1] *= s;
return m1; return m1;
} }
template<RealType T>
TMatrix2<T>& operator*= (TMatrix2<T>& m1, const TMatrix2<T>& m2)
{
TMatrix2<T> c = m1;
m1(0, 0) = c(0, 0) * m2(0, 0) + c(0, 1) * m2(1, 0); template <RealType T>
m1(0, 1) = c(0, 0) * m2(0, 1) + c(0, 1) * m2(1, 1); TMatrix2<T>& operator*=(TMatrix2<T>& m1, T s)
{
m1.data[0][0] *= s;
m1.data[0][1] *= s;
m1.data[1][0] *= s;
m1.data[1][1] *= s;
m1(1, 0) = c(1, 0) * m2(0, 0) + c(1, 1) * m2(1, 0); return m1;
m1(1, 1) = c(1, 0) * m2(0, 1) + c(1, 1) * m2(1, 1); }
return m1; template <RealType T>
} TMatrix2<T>& operator*=(TMatrix2<T>& m1, const TMatrix2<T>& m2)
{
TMatrix2<T> c = m1;
template<RealType T> m1(0, 0) = c(0, 0) * m2(0, 0) + c(0, 1) * m2(1, 0);
TMatrix2<T>& operator/= (TMatrix2<T>& m1, T s) m1(0, 1) = c(0, 0) * m2(0, 1) + c(0, 1) * m2(1, 1);
{
s = (T)1.0 / s;
m1.data[0][0] *= s;
m1.data[0][1] *= s;
m1.data[1][0] *= s;
m1.data[1][1] *= s;
return m1; m1(1, 0) = c(1, 0) * m2(0, 0) + c(1, 1) * m2(1, 0);
} m1(1, 1) = c(1, 0) * m2(0, 1) + c(1, 1) * m2(1, 1);
template<RealType T> return m1;
TMatrix2<T> operator+ (const TMatrix2<T>& m1, T s) }
{
return TMatrix2<T>(m1(0, 0) + s, m1(0, 1) + s,
m1(1, 0) + s, m1(1, 1) + s);
}
template<RealType T>
TMatrix2<T> operator+ (const TMatrix2<T>& m1, const TMatrix2<T>& m2)
{
return TMatrix2<T>(m1(0, 0) + m2(0, 0), m1(0, 1) + m2(0, 1),
m1(1, 0) + m2(1, 0), m1(1, 1) + m2(1, 1));
}
template<RealType T> template <RealType T>
TMatrix2<T> operator- (const TMatrix2<T>& m1, T s) TMatrix2<T>& operator/=(TMatrix2<T>& m1, T s)
{ {
return TMatrix2<T>(m1(0, 0) - s, m1(0, 1) - s, s = (T)1.0 / s;
m1(1, 0) - s, m1(1, 1) - s); m1.data[0][0] *= s;
} m1.data[0][1] *= s;
m1.data[1][0] *= s;
template<RealType T> m1.data[1][1] *= s;
TMatrix2<T> operator- (const TMatrix2<T>& m1, const TMatrix2<T>& m2)
{
return TMatrix2<T>(m1(0, 0) - m2(0, 0), m1(0, 1) - m2(0, 1),
m1(1, 0) - m2(1, 0), m1(1, 1) - m2(1, 1));
}
template<RealType T> return m1;
TMatrix2<T> operator* (const TMatrix2<T>& m1, T s) }
{
return TMatrix2<T>(m1(0, 0) * s, m1(0, 1) * s,
m1(1, 0) * s, m1(1, 1) * s);
}
template<RealType T> template <RealType T>
TMatrix2<T> operator/ (const TMatrix2<T>& m1, T s) TMatrix2<T> operator+(const TMatrix2<T>& m1, T s)
{ {
s = (T)1.0 / s; return TMatrix2<T>(m1(0, 0) + s, m1(0, 1) + s, m1(1, 0) + s, m1(1, 1) + s);
return TMatrix2<T>(m1(0, 0) * s, m1(0, 1) * s, }
m1(1, 0) * s, m1(1, 1) * s);
}
template<RealType T>
TMatrix2<T> operator* (const TMatrix2<T>& m1, const TMatrix2<T>& m2)
{
return TMatrix2<T>(m1(0, 0) * m2(0, 0) + m1(0, 1) * m2(1, 0), m1(0, 0) * m2(0, 1) + m1(0, 1) * m2(1, 1),
m1(1, 0) * m2(0, 0) + m1(1, 1) * m2(1, 0), m1(1, 0) * m2(0, 1) + m1(1, 1) * m2(1, 1));
}
template<RealType T>
TVector2<T, false> operator* (const TMatrix2<T>& m1, const TVector2<T, false>& v)
{
return TVector2<T, false>(m1(0, 0) * v.x + m1(0, 1) * v.y,
m1(1, 0) * v.x + m1(1, 1) * v.y);
}
template<RealType T> template <RealType T>
bool operator== (const TMatrix2<T>& m1, const TMatrix2<T>& m2) TMatrix2<T> operator+(const TMatrix2<T>& m1, const TMatrix2<T>& m2)
{ {
return m1[0] == m2[0] && m1[1] == m2[1]; return TMatrix2<T>(
} m1(0, 0) + m2(0, 0), m1(0, 1) + m2(0, 1), m1(1, 0) + m2(1, 0), m1(1, 1) + m2(1, 1));
}
template<RealType T> template <RealType T>
bool operator!= (const TMatrix2<T>& m1, const TMatrix2<T>& m2) TMatrix2<T> operator-(const TMatrix2<T>& m1, T s)
{ {
return m1[0] != m2[0] || m1[1] != m2[1]; return TMatrix2<T>(m1(0, 0) - s, m1(0, 1) - s, m1(1, 0) - s, m1(1, 1) - s);
} }
template <RealType T>
TMatrix2<T> operator-(const TMatrix2<T>& m1, const TMatrix2<T>& m2)
{
return TMatrix2<T>(
m1(0, 0) - m2(0, 0), m1(0, 1) - m2(0, 1), m1(1, 0) - m2(1, 0), m1(1, 1) - m2(1, 1));
}
// ============================== // template <RealType T>
// Matrix function definition // TMatrix2<T> operator*(const TMatrix2<T>& m1, T s)
// ============================== // {
return TMatrix2<T>(m1(0, 0) * s, m1(0, 1) * s, m1(1, 0) * s, m1(1, 1) * s);
}
template<RealType T> template <RealType T>
T Determinant(const TMatrix2<T>& m1) TMatrix2<T> operator/(const TMatrix2<T>& m1, T s)
{ {
return m1(0, 0) * m1(1, 1) - m1(0, 1) * m1(1, 0); s = (T)1.0 / s;
} return TMatrix2<T>(m1(0, 0) * s, m1(0, 1) * s, m1(1, 0) * s, m1(1, 1) * s);
}
template<RealType T> template <RealType T>
TMatrix2<T>& InverseV(TMatrix2<T>& m1) TMatrix2<T> operator*(const TMatrix2<T>& m1, const TMatrix2<T>& m2)
{ {
float _1_det = 1.0f / Determinant(m1); return TMatrix2<T>(m1(0, 0) * m2(0, 0) + m1(0, 1) * m2(1, 0),
float m00 = m1(0, 0); m1(0, 0) * m2(0, 1) + m1(0, 1) * m2(1, 1),
m1(1, 0) * m2(0, 0) + m1(1, 1) * m2(1, 0),
m1(1, 0) * m2(0, 1) + m1(1, 1) * m2(1, 1));
}
m1(0, 0) = m1(1, 1); template <RealType T>
m1(0, 1) = -m1(0, 1); TVector2<T, false> operator*(const TMatrix2<T>& m1, const TVector2<T, false>& v)
m1(1, 0) = -m1(1, 0); {
m1(1, 1) = m00; return TVector2<T, false>(m1(0, 0) * v.x + m1(0, 1) * v.y, m1(1, 0) * v.x + m1(1, 1) * v.y);
}
m1 *= _1_det; template <RealType T>
return m1; bool operator==(const TMatrix2<T>& m1, const TMatrix2<T>& m2)
} {
return m1[0] == m2[0] && m1[1] == m2[1];
}
template<RealType T> template <RealType T>
TMatrix2<T>& TransposeV(TMatrix2<T>& m1) bool operator!=(const TMatrix2<T>& m1, const TMatrix2<T>& m2)
{ {
Swap(m1(0, 1), m1(1, 0)); return m1[0] != m2[0] || m1[1] != m2[1];
}
return m1; // ============================== //
} // Matrix function definition //
// ============================== //
// =============== // template <RealType T>
// WITH RETURN // T Determinant(const TMatrix2<T>& m1)
// =============== // {
return m1(0, 0) * m1(1, 1) - m1(0, 1) * m1(1, 0);
}
template<RealType T> template <RealType T>
TMatrix2<T> Inverse(TMatrix2<T>& m1) TMatrix2<T>& InverseV(TMatrix2<T>& m1)
{ {
float _1_det = 1.0f / Determinant(m1); float _1_det = 1.0f / Determinant(m1);
float m00 = m1(0, 0);
return TMatrix2<T>( m1(1, 1) * _1_det, -m1(0, 1) * _1_det, m1(0, 0) = m1(1, 1);
-m1(1, 0) * _1_det, m1(0, 0) * _1_det); m1(0, 1) = -m1(0, 1);
} m1(1, 0) = -m1(1, 0);
m1(1, 1) = m00;
template<RealType T> m1 *= _1_det;
TMatrix2<T> Transpose(const TMatrix2<T>& m1) return m1;
{ }
return TMatrix2<T>(m1(0, 0), m1(1, 0),
m1(0, 1), m1(1, 1));
}
template<RealType T> template <RealType T>
bool IsIdentityMatrix(const TMatrix2<T>& m1, T threshold = P_FLT_INAC) TMatrix2<T>& TransposeV(TMatrix2<T>& m1)
{ {
return (abs(m1(0, 0) - (T)1.0) < P_FLT_INAC && abs(m1(0, 1)) < P_FLT_INAC && Swap(m1(0, 1), m1(1, 0));
abs(m1(1, 0)) < P_FLT_INAC && abs(m1(1, 1) - (T)1.0) < P_FLT_INAC);
}
} // Phanes::Core::Math return m1;
}
// =============== //
// WITH RETURN //
// =============== //
template <RealType T>
TMatrix2<T> Inverse(TMatrix2<T>& m1)
{
float _1_det = 1.0f / Determinant(m1);
return TMatrix2<T>(
m1(1, 1) * _1_det, -m1(0, 1) * _1_det, -m1(1, 0) * _1_det, m1(0, 0) * _1_det);
}
template <RealType T>
TMatrix2<T> Transpose(const TMatrix2<T>& m1)
{
return TMatrix2<T>(m1(0, 0), m1(1, 0), m1(0, 1), m1(1, 1));
}
template <RealType T>
bool IsIdentityMatrix(const TMatrix2<T>& m1, T threshold = P_FLT_INAC)
{
return (abs(m1(0, 0) - (T)1.0) < P_FLT_INAC && abs(m1(0, 1)) < P_FLT_INAC &&
abs(m1(1, 0)) < P_FLT_INAC && abs(m1(1, 1) - (T)1.0) < P_FLT_INAC);
}
} // namespace Phanes::Core::Math
#endif // !MATRIX2_H #endif // !MATRIX2_H
#include "Core/Math/SIMD/SIMDIntrinsics.h"
#include "Core/Math/SIMD/SIMDIntrinsics.h"

View File

@@ -83,7 +83,7 @@ namespace Phanes::Core::Math {
/// Construct matrix from field of values. /// Construct matrix from field of values.
/// </summary> /// </summary>
/// <param name="field"></param> /// <param name="field"></param>
TMatrix4(T field[4][4]) explicit TMatrix4(T field[4][4])
{ {
this->c0 = TVector4(field[0]); this->c0 = TVector4(field[0]);
this->c1 = TVector4(field[1]); this->c1 = TVector4(field[1]);
@@ -331,4 +331,4 @@ namespace Phanes::Core::Math {
#endif // !MATRIX4_H #endif // !MATRIX4_H
#include "Core/Math/Matrix4.inl" #include "Core/Math/Matrix4.inl"

View File

@@ -0,0 +1,85 @@
#pragma once
#include "Core/Math/Boilerplate.h"
#include "Core/Math/MathFwd.h"
#include "Core/Math/SIMD/PhanesSIMDTypes.h"
#include "Core/Math/SIMD/Storage.h"
#include "Core/Math/Vector3.hpp"
#include "Core/Math/Vector4.hpp"
#ifndef QUATERNION_H
# define QUATERNION_H
namespace Phanes::Core::Math
{
// Quaternion
template <RealType T, bool S>
struct TQuaternion
{
using Real = T;
public:
union
{
struct
{
float x;
float y;
float z;
float w;
};
union
{
typename SIMD::Storage<4, Real, SIMD::use_simd<Real, 4, S>::value>::type comp;
typename SIMD::Storage<4, Real, SIMD::use_simd<Real, 4, S>::value>::type data;
};
};
public:
/// Default constructor
TQuaternion() = default;
/**
* Construct quaternion from vector4.
* v.w is the scalar part of the quaternion (q.w).
*/
explicit TQuaternion(const TVector4<T, S>& v);
/**
* Construct quaternion from vector (x,y,z) and scalar part (w).
*
* @param x X
* @param y Y
* @param z Z
* @param w W
*/
TQuaternion(Real x, Real y, Real z, Real w);
/**
* Construct vector from vector part and scalar part.
*/
TQuaternion(const TVector3<Real, S>& v, Real w);
/**
* Construct quaternion from array of length >= four.
*
* @note If used with SIMD the array will is assumed to be aligned.
*/
explicit TQuaternion(const Real* comp);
/**
* Construct from euler angles (yaw, pitch, roll)
*/
explicit TQuaternion(const TVector3<Real, S>& euler_angels);
/**
* Construct from Transformation
*/
explicit TQuaternion(const TTransform<Real>& t);
explicit TQuaternion(const TMatrix4<Real, S>& t);
};
} // namespace Phanes::Core::Math
#endif // QUATERNION_H

View File

@@ -1,158 +1,154 @@
#pragma once #pragma once
// This file includes the necessary header for vectorization intrinsics. If no specifics are defined SSE4.2 is used. // This file includes the necessary header for vectorization intrinsics. If no specifics are defined SSE4.2 is used.
// //
// ARM is not supported. // ARM is not supported.
#include "Core/Math/SIMD/Platform.h"
#include "Core/Math/MathTypes.h" #include "Core/Math/MathTypes.h"
#include "Core/Math/SIMD/Platform.h"
#if P_INTRINSICS == P_INTRINSICS_AVX2 #if P_INTRINSICS == P_INTRINSICS_AVX2
# include <immintrin.h> # include <immintrin.h>
#elif P_INTRINSICS == P_INTRINSICS_AVX #elif P_INTRINSICS == P_INTRINSICS_AVX
# include <immintrin.h> # include <immintrin.h>
#elif P_INTRINSICS == P_INTRINSICS_SSE #elif P_INTRINSICS == P_INTRINSICS_SSE
# include <nmmintrin.h> # include <nmmintrin.h>
#elif P_INTRINSICS == P_INTRINSICS_NEON #elif P_INTRINSICS == P_INTRINSICS_NEON
# include "neon.h" // <- Not supported # include "neon.h" // <- Not supported
#endif #endif
// use_simd for metaprogramming // use_simd for metaprogramming
namespace Phanes::Core::Math::SIMD namespace Phanes::Core::Math::SIMD
{ {
/// <summary>
/// This decides, whether simd operations should be used, based on the vector type, it's size, the vector alignment and whether the right extension can be loaded during compiletime.
/// </summary>
/// <typeparam name="T">Type of vector</typeparam>
/// <typeparam name="L">Length of vector</typeparam>
/// <typeparam name="IsAligned">Whether the vector is aligned for simd usage.</typeparam>
template<typename T, size_t L, bool IsAligned>
struct use_simd
{
static const bool value = false;
};
/// <summary>
/// This decides, whether simd operations should be used, based on the vector type, it's size, the vector alignment and whether the right extension can be loaded during compiletime.
/// </summary>
/// <typeparam name="T">Type of vector</typeparam>
/// <typeparam name="L">Length of vector</typeparam>
/// <typeparam name="IsAligned">Whether the vector is aligned for simd usage.</typeparam>
template <typename T, size_t L, bool IsAligned>
struct use_simd
{
static const bool value = false;
};
// SSE / NEON // SSE / NEON
template<> template <>
struct use_simd<float, 4, true> struct use_simd<float, 4, true>
{ {
static const bool value = true && (P_SSE__ || P_NEON__); static const bool value = (P_SSE__ || P_NEON__);
}; };
template<> template <>
struct use_simd<float, 3, true> struct use_simd<float, 3, true>
{ {
static const bool value = true && (P_SSE__ || P_NEON__); static const bool value = (P_SSE__ || P_NEON__);
}; };
template<> template <>
struct use_simd<int, 4, true> struct use_simd<int, 4, true>
{ {
static const bool value = true && (P_SSE__ || P_NEON__); static const bool value = (P_SSE__ || P_NEON__);
}; };
template<> template <>
struct use_simd<int, 3, true> struct use_simd<int, 3, true>
{ {
static const bool value = true && (P_SSE__ || P_NEON__); static const bool value = (P_SSE__ || P_NEON__);
}; };
template<> template <>
struct use_simd<unsigned int, 4, true> struct use_simd<unsigned int, 4, true>
{ {
static const bool value = true && (P_SSE__ || P_NEON__); static const bool value = (P_SSE__ || P_NEON__);
}; };
template<> template <>
struct use_simd<unsigned int, 3, true> struct use_simd<unsigned int, 3, true>
{ {
static const bool value = true && (P_SSE__ || P_NEON__); static const bool value = (P_SSE__ || P_NEON__);
}; };
// SSE // SSE
template<> template <>
struct use_simd<double, 2, true> struct use_simd<double, 2, true>
{ {
static const bool value = true && P_SSE__; static const bool value = P_SSE__;
}; };
template<> template <>
struct use_simd<Phanes::Core::Types::int64, 2, true> struct use_simd<Phanes::Core::Types::int64, 2, true>
{ {
static const bool value = true && P_SSE__; static const bool value = P_SSE__;
}; };
template<> template <>
struct use_simd<Phanes::Core::Types::uint64, 2, true> struct use_simd<Phanes::Core::Types::uint64, 2, true>
{ {
static const bool value = true && P_SSE__; static const bool value = P_SSE__;
}; };
// AVX
template <>
struct use_simd<double, 4, true>
{
static const bool value = P_AVX__;
};
// AVX template <>
struct use_simd<double, 3, true>
{
static const bool value = P_AVX__;
};
template<> template <>
struct use_simd<double, 4, true> struct use_simd<float, 8, true>
{ {
static const bool value = true && P_AVX__; static const bool value = P_AVX__;
}; };
template<> // AVX2
struct use_simd<double, 3, true>
{
static const bool value = true && P_AVX__;
};
template<> template <>
struct use_simd<float, 8, true> struct use_simd<Phanes::Core::Types::int64, 4, true>
{ {
static const bool value = true && P_AVX__; static const bool value = P_AVX2__;
}; };
template <>
struct use_simd<Phanes::Core::Types::int64, 3, true>
{
static const bool value = P_AVX2__;
};
// AVX2 template <>
struct use_simd<Phanes::Core::Types::uint64, 4, true>
{
static const bool value = P_AVX2__;
};
template<> template <>
struct use_simd<Phanes::Core::Types::int64, 4, true> struct use_simd<Phanes::Core::Types::uint64, 3, true>
{ {
static const bool value = true && P_AVX2__; static const bool value = P_AVX2__;
}; };
template<> template <>
struct use_simd<Phanes::Core::Types::int64, 3, true> struct use_simd<int, 8, true>
{ {
static const bool value = true && P_AVX2__; static const bool value = P_AVX2__;
}; };
template<> template <>
struct use_simd<Phanes::Core::Types::uint64, 4, true> struct use_simd<unsigned int, 8, true>
{ {
static const bool value = true && P_AVX2__; static const bool value = P_AVX2__;
}; };
} // namespace Phanes::Core::Math::SIMD
template<>
struct use_simd<Phanes::Core::Types::uint64, 3, true>
{
static const bool value = true && P_AVX2__;
};
template<>
struct use_simd<int, 8, true>
{
static const bool value = true && P_AVX2__;
};
template<>
struct use_simd<unsigned int, 8, true>
{
static const bool value = true && P_AVX2__;
};
}
// Register aliases // Register aliases
namespace Phanes::Core::Types namespace Phanes::Core::Types
@@ -160,69 +156,123 @@ namespace Phanes::Core::Types
#if P_INTRINSICS >= 1 #if P_INTRINSICS >= 1
typedef __m128 Vec4f32Reg; using Vec4f32Reg = __m128;
typedef __m128d Vec2f64Reg; using Vec2f64Reg = __m128d;
typedef __m128i Vec4i32Reg; using Vec4i32Reg = __m128i;
typedef __m128i Vec2i64Reg; using Vec2i64Reg = __m128i;
typedef __m128i Vec4u32Reg; using Vec4u32Reg = __m128i;
typedef __m128i Vec2u64Reg; using Vec2u64Reg = __m128i;
#elif P_INTRINSICS != P_INTRINSICS_NEON #elif P_INTRINSICS != P_INTRINSICS_NEON
typedef struct alignas(16) Vec4f32Reg { float data[4]; } Vec4f32Reg; using Vec4f32Reg = struct alignas(16) Vec4f32Reg
typedef struct alignas(16) Vec2f64Reg { double data[2]; } Vec2f64Reg; {
typedef struct alignas(16) Vec4i32Reg { int data[4]; } Vec4i32Reg; float data[4];
typedef struct alignas(16) Vec2i64Reg { Phanes::Core::Types::int64 data[2]; } Vec2i64Reg; };
typedef struct alignas(16) Vec4u32Reg { unsigned int data[4]; } Vec4u32Reg; using Vec2f64Reg = struct alignas(16) Vec2f64Reg
typedef struct alignas(16) Vec2u64Reg { Phanes::Core::Types::uint64 data[4]; } Vec2u64Reg; {
double data[2];
};
using Vec4i32Reg = struct alignas(16) Vec4i32Reg
{
int data[4];
};
using Vec2i64Reg = struct alignas(16) Vec2i64Reg
{
Phanes::Core::Types::int64 data[2];
};
using Vec4u32Reg = struct alignas(16) Vec4u32Reg
{
unsigned int data[4];
};
using Vec2u64Reg = struct alignas(16) Vec2u64Reg
{
Phanes::Core::Types::uint64 data[4];
};
#endif #endif
#if P_INTRINSICS >= 2 #if P_INTRINSICS >= 2
typedef __m256 Vec4x2f32Reg; using Vec4x2f32Reg = __m256;
typedef __m256 Vec8f32Reg; using Vec8f32Reg = __m256;
typedef __m256d Vec2x2f64Reg; using Vec2x2f64Reg = __m256d;
typedef __m256d Vec4f64Reg; using Vec4f64Reg = __m256d;
#elif P_INTRINSICS != P_INTRINSICS_NEON #elif P_INTRINSICS != P_INTRINSICS_NEON
typedef struct alignas(32) Vec4x2f32Reg { float data[8]; } Vec4x2f32Reg; using Vec4x2f32Reg = struct alignas(32) Vec4x2f32Reg
typedef struct alignas(32) Vec8f32Reg { float data[8]; } Vec8f32Reg; {
typedef struct alignas(32) Vec2x2f64Reg { double data[4]; } Vec2x2f64Reg; float data[8];
typedef struct alignas(32) Vec4f64Reg { double data[4]; } Vec4f64Reg; };
using Vec8f32Reg = struct alignas(32) Vec8f32Reg
{
float data[8];
};
using Vec2x2f64Reg = struct alignas(32) Vec2x2f64Reg
{
double data[4];
};
using Vec4f64Reg = struct alignas(32) Vec4f64Reg
{
double data[4];
};
#endif #endif
#if P_INTRINSICS == 3 #if P_INTRINSICS == 3
typedef __m256i Vec4x2i32Reg; using Vec4x2i32Reg = __m256i;
typedef __m256i Vec8i32Reg; using Vec8i32Reg;
typedef __m256i Vec2x2i64Reg; = __m256i using Vec2x2i64Reg;
typedef __m256i Vec4i64Reg; = __m256i using Vec4i64Reg;
= __m256i
typedef __m256i Vec4x2u32Reg; using Vec4x2u32Reg;
typedef __m256i Vec8u32Reg; = __m256i using Vec8u32Reg;
typedef __m256i Vec2x2u64Reg; = __m256i using Vec2x2u64Reg;
typedef __m256i Vec4u64Reg; = __m256i using Vec4u64Reg;
= __m256i
#elif P_INTRINSICS != P_INTRINSICS_NEON #elif P_INTRINSICS != P_INTRINSICS_NEON
typedef struct alignas(32) Vec4x2i32Reg { int data[8]; } Vec4x2i32Reg; using Vec4x2i32Reg = struct alignas(32) Vec4x2i32Reg
typedef struct alignas(32) Vec8i32Reg { int data[8]; } Vec8i32Reg; {
typedef struct alignas(32) Vec2x2i64Reg { Phanes::Core::Types::int64 data[4]; } Vec2x2i64Reg; int data[8];
typedef struct alignas(32) Vec4i64Reg { Phanes::Core::Types::int64 data[4]; } Vec4i64Reg; };
using Vec8i32Reg = struct alignas(32) Vec8i32Reg
{
int data[8];
};
using Vec2x2i64Reg = struct alignas(32) Vec2x2i64Reg
{
Phanes::Core::Types::int64 data[4];
};
using Vec4i64Reg = struct alignas(32) Vec4i64Reg
{
Phanes::Core::Types::int64 data[4];
};
typedef struct alignas(32) Vec4x2u32Reg { unsigned int data[8]; } Vec4x2u32Reg; using Vec4x2u32Reg = struct alignas(32) Vec4x2u32Reg
typedef struct alignas(32) Vec8u32Reg { unsigned int data[8]; } Vec8u32Reg; {
typedef struct alignas(32) Vec2x2u64Reg { Phanes::Core::Types::uint64 data[4]; } Vec2x2u64Reg; unsigned int data[8];
typedef struct alignas(32) Vec4u64Reg { Phanes::Core::Types::uint64 data[4]; } Vec4u64Reg; };
using Vec8u32Reg = struct alignas(32) Vec8u32Reg
{
unsigned int data[8];
};
using Vec2x2u64Reg = struct alignas(32) Vec2x2u64Reg
{
Phanes::Core::Types::uint64 data[4];
};
using Vec4u64Reg = struct alignas(32) Vec4u64Reg
{
Phanes::Core::Types::uint64 data[4];
};
#endif #endif
// NEON ... // NEON ...
} } // namespace Phanes::Core::Types

View File

@@ -1,74 +1,80 @@
#pragma once #pragma once
#include "Core/public/Math/SIMD/PhanesSIMDTypes.h" #include "Core/Math/MathCommon.hpp"
#include "Core/public/Math/MathCommon.hpp" #include "Core/Math/SIMD/PhanesSIMDTypes.h"
namespace Phanes::Core::Math::SIMD namespace Phanes::Core::Math::SIMD
{ {
/// <summary> /// <summary>
/// Adds all scalars of the vector. /// Adds all scalars of the vector.
/// </summary> /// </summary>
/// <param name="v">Vector</param> /// <param name="v">Vector</param>
/// <returns>Sum stored in v[0:31].</returns> /// <returns>Sum stored in v[0:31].</returns>
Phanes::Core::Types::Vec4f32Reg vec4_hadd(const Phanes::Core::Types::Vec4f32Reg v) Phanes::Core::Types::Vec4f32Reg vec4_hadd(const Phanes::Core::Types::Vec4f32Reg v)
{ {
Phanes::Core::Types::Vec4f32Reg r; Phanes::Core::Types::Vec4f32Reg r;
r.data[0] = v.data[0] + v.data[1] + v.data[2] + v.data[3]; r.data[0] = v.data[0] + v.data[1] + v.data[2] + v.data[3];
} }
/// <summary>
/// Adds all scalars of the vector.
/// </summary>
/// <param name="v">Vector</param>
/// <returns>Sum of components.</returns>
float vec4_hadd_cvtf32(const Phanes::Core::Types::Vec4f32Reg v)
{
return v.data[0] + v.data[1] + v.data[2] + v.data[3];
}
/// <summary>
/// Gets the absolute value of each scalar in the vector.
/// </summary>
/// <param name="v">Vector</param>
/// <returns>Vector with all components positive.</returns>
Phanes::Core::Types::Vec4f32Reg vec4_abs(const Phanes::Core::Types::Vec4f32Reg v)
{
Phanes::Core::Types::Vec4f32Reg r;
r.data[0] = Abs(v.data[0]); /// <summary>
} /// Adds all scalars of the vector.
/// </summary>
/// <summary> /// <param name="v">Vector</param>
/// Gets the dot product of the /// <returns>Sum of components.</returns>
/// </summary> float vec4_hadd_cvtf32(const Phanes::Core::Types::Vec4f32Reg v)
/// <param name="v1"></param> {
/// <param name="v2"></param> return v.data[0] + v.data[1] + v.data[2] + v.data[3];
/// <returns></returns> }
Phanes::Core::Types::Vec4f32Reg vec4_dot(const Phanes::Core::Types::Vec4f32Reg v1, const Phanes::Core::Types::Vec4f32Reg v2)
{
Phanes::Core::Types::Vec4f32Reg r;
r.data[0] = v1.data[0] * v1.data[0] + v1.data[1] * v2.data[1] + v1.data[2] * v2.data[2] + v1.data[3] * v2.data[3];
return r; /// <summary>
} /// Gets the absolute value of each scalar in the vector.
/// </summary>
/// <summary> /// <param name="v">Vector</param>
/// Gets the dot product of the /// <returns>Vector with all components positive.</returns>
/// </summary> Phanes::Core::Types::Vec4f32Reg vec4_abs(const Phanes::Core::Types::Vec4f32Reg v)
/// <param name="v1"></param> {
/// <param name="v2"></param> Phanes::Core::Types::Vec4f32Reg r;
/// <returns></returns>
float vec4_dot_cvtf32(const Phanes::Core::Types::Vec4f32Reg v1, const Phanes::Core::Types::Vec4f32Reg v2)
{
return v1.data[0] * v1.data[0] + v1.data[1] * v2.data[1] + v1.data[2] * v2.data[2] + v1.data[3] * v2.data[3];
}
Phanes::Core::Types::Vec2f64Reg vec2_eq(const Phanes::Core::Types::Vec2f64Reg v1, const Phanes::Core::Types::Vec2f64Reg v2) r.data[0] = Abs(v.data[0]);
{ }
Phanes::Core::Types::Vec4f64Reg r;
r.data[0] = (Phanes::Core::Math::Abs(v1.data[0] - v2.data[0]) < P_FLT_INAC) ? 0xFFFFFFFF : 0; /// <summary>
r.data[1] = (Phanes::Core::Math::Abs(v1.data[1] - v2.data[1]) < P_FLT_INAC) ? 0xFFFFFFFF : 0; /// Gets the dot product of the
} /// </summary>
} /// <param name="v1"></param>
/// <param name="v2"></param>
/// <returns></returns>
Phanes::Core::Types::Vec4f32Reg vec4_dot(const Phanes::Core::Types::Vec4f32Reg v1,
const Phanes::Core::Types::Vec4f32Reg v2)
{
Phanes::Core::Types::Vec4f32Reg r;
r.data[0] = v1.data[0] * v1.data[0] + v1.data[1] * v2.data[1] + v1.data[2] * v2.data[2] +
v1.data[3] * v2.data[3];
return r;
}
/// <summary>
/// Gets the dot product of the
/// </summary>
/// <param name="v1"></param>
/// <param name="v2"></param>
/// <returns></returns>
float vec4_dot_cvtf32(const Phanes::Core::Types::Vec4f32Reg v1,
const Phanes::Core::Types::Vec4f32Reg v2)
{
return v1.data[0] * v1.data[0] + v1.data[1] * v2.data[1] + v1.data[2] * v2.data[2] +
v1.data[3] * v2.data[3];
}
Phanes::Core::Types::Vec2f64Reg vec2_eq(const Phanes::Core::Types::Vec2f64Reg v1,
const Phanes::Core::Types::Vec2f64Reg v2)
{
Phanes::Core::Types::Vec4f64Reg r;
r.data[0] =
(Phanes::Core::Math::Abs(v1.data[0] - v2.data[0]) < P_FLT_INAC) ? 0xFFFFFFFF : 0;
r.data[1] =
(Phanes::Core::Math::Abs(v1.data[1] - v2.data[1]) < P_FLT_INAC) ? 0xFFFFFFFF : 0;
}
} // namespace Phanes::Core::Math::SIMD

File diff suppressed because it is too large Load Diff

View File

@@ -1,21 +0,0 @@
#include <iostream>
#include "Core/Math/Include.h"
namespace PMath = Phanes::Core::Math;
int main()
{
PMath::Matrix4 m0 = PMath::Matrix4(1.0f, 5.0f, 3.0f, 4.0f,
2.0f, 6.0f, 4.0f, 1.0f,
2.0f, -3.0f, 5.0f, 3.0f,
8.0f, -4.0f, 6.0f, -2.0f);
PMath::Matrix4 m2;
std::cout << std::to_string(PMath::InverseV<float, false>(m0)) << std::endl;
std::cout << PMath::ToString(m0) << std::endl;
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,2 +1,45 @@
# PhanesEngine # PhanesEngine
3D / 2D Game Engine.
Yet another Game Engine written in C++.
## Build
For building the engine premake5 is required. Execute `premake5 gmake` to generate the Makefile.
### PhanesCore
The Core Runtime library is build with:
make PhanesCore
## Status
Phanes is and will be developed, though progress will be slow.
### Currenty under development
- PhanesCore
- <span style="color:green; font-weight:800">Math</span>
## Testing
Testing PhanesEngine happens via the gtest framework. To run the tests for PhanesEngine one needs to
build the test applications (currently only MathTestFPU) as well as gtet.
make MathTestFPU
They depend on the gtest library so it should not be required to build it manually. If for some reason this doesn't
work gtest can be build via:
make gtest
## Sample Project
The repository contains a sample game project using PhanesEngine. It can be build by executing:
make DevPlayground
## Copyright
PhanesEngine was developed by Thorben Höhne and is licensed under the Apache License Version 2.0. See
[LICENSE](LICENSE) for more information.

View File

@@ -63,17 +63,19 @@ function boilerplate()
buildoptions({ "-Wno-unused-parameter", "-fms-extensions" }) buildoptions({ "-Wno-unused-parameter", "-fms-extensions" })
end end
buildoptions({"-fno-fast-math"})
filter("configurations:Debug") filter("configurations:Debug")
defines({ "DEBUG", "TRACE", "P_DEBUG" }) defines({ "DEBUG", "TRACE", "P_DEBUG" })
symbols("On") symbols("On")
buildmessage("Building %{prj.name} in debug mode") buildmessage("Building %{prj.name} in debug mode")
filter("configurations:Release") filter("configurations:Release")
defines({ "NDEBUG", "P_RELEASE" }) defines({ "NDEBUG", "P_RELEASE" })
linktimeoptimization("On") linktimeoptimization("On")
optimize("On") optimize("On")
intrinsics("On") intrinsics("On")
buildmessage("Building %{prj.name} in release mode") buildmessage("Building %{prj.name} in release mode")
filter({}) filter({})
end end