From ce9758c86b398f5ab43fce76dda10445a5fd561a Mon Sep 17 00:00:00 2001 From: Orange Date: Fri, 31 Oct 2025 16:05:44 +0300 Subject: [PATCH] Adds dark theme support to the OM documentation Applies a dark theme to the documentation site using the `darkly` theme. Provides a visually appealing dark mode option. Configures colors to ensure readability and aesthetic consistency. --- docs/index.md | 75 +++++- docs/linear_algebra/mat.md | 428 +++++++++++++++++++++++++++++++++ docs/styles/dark-overrides.css | 67 ++++++ mkdocs.yml | 4 +- 4 files changed, 561 insertions(+), 13 deletions(-) create mode 100644 docs/linear_algebra/mat.md create mode 100644 docs/styles/dark-overrides.css diff --git a/docs/index.md b/docs/index.md index 000ea34..70faad5 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,17 +1,68 @@ -# Welcome to MkDocs +# Installation -For full documentation visit [mkdocs.org](https://www.mkdocs.org). +## Using vcpkg +**Note**: Support vcpkg for package management +1. Install [vcpkg](https://github.com/microsoft/vcpkg) +2. Run the following command to install the orange-math package: +``` +vcpkg install orange-math +``` +CMakeLists.txt +```cmake +find_package(omath CONFIG REQUIRED) +target_link_libraries(main PRIVATE omath::omath) +``` +For detailed commands on installing different versions and more information, please refer to Microsoft's [official instructions](https://learn.microsoft.com/en-us/vcpkg/get_started/overview). -## Commands +## Using xrepo +**Note**: Support xrepo for package management +1. Install [xmake](https://xmake.io/) +2. Run the following command to install the omath package: +``` +xrepo install omath +``` +xmake.lua +```xmake +add_requires("omath") +target("...") + add_packages("omath") +``` -* `mkdocs new [dir-name]` - Create a new project. -* `mkdocs serve` - Start the live-reloading docs server. -* `mkdocs build` - Build the documentation site. -* `mkdocs -h` - Print help message and exit. +## Build from source using CMake +1. **Preparation** -## Project layout + Install needed tools: cmake, clang, git, msvc (windows only). - mkdocs.yml # The configuration file. - docs/ - index.md # The documentation homepage. - ... # Other markdown pages, images and other files. + 1. **Linux:** + ```bash + sudo pacman -Sy cmake ninja clang git + ``` + 2. **MacOS:** + ```bash + brew install llvm git cmake ninja + ``` + 3. **Windows:** + + Install Visual Studio from [here](https://visualstudio.microsoft.com/downloads/) and Git from [here](https://git-scm.com/downloads). + + Use x64 Native Tools shell to execute needed commands down below. +2. **Clone the repository:** + ```bash + git clone https://github.com/orange-cpp/omath.git + ``` +3. **Navigate to the project directory:** + ```bash + cd omath + ``` +4. **Build the project using CMake:** + ```bash + cmake --preset windows-release -S . + cmake --build cmake-build/build/windows-release --target omath -j 6 + ``` + Use **\-\** preset to build suitable version for yourself. Like **windows-release** or **linux-release**. + + | Platform Name | Build Config | + |---------------|---------------| + | windows | release/debug | + | linux | release/debug | + | darwin | release/debug | diff --git a/docs/linear_algebra/mat.md b/docs/linear_algebra/mat.md new file mode 100644 index 0000000..b54cc3b --- /dev/null +++ b/docs/linear_algebra/mat.md @@ -0,0 +1,428 @@ +# `omath::Mat` + +> Header: your project’s `mat.hpp` (requires `vector3.hpp`) +> Namespace: `omath` +> Requires: **C++23** (uses multi-parameter `operator[]`) +> SIMD (optional): define **`OMATH_USE_AVX2`** to enable AVX2-accelerated multiplication for `float`/`double`. + +--- + +## Overview + +`omath::Mat` is a compile-time, fixed-size matrix with: + +* **Row/column counts** as template parameters (no heap allocations). +* **Row-major** or **column-major** storage (compile-time via `MatStoreType`). +* **Arithmetic** and **linear algebra**: matrix × matrix, scalar ops, transpose, determinant, inverse (optional), etc. +* **Transform helpers**: translation, axis rotations, look-at, perspective & orthographic projections. +* **I/O helpers**: `to_string`/`to_wstring`/`to_u8string` and `std::formatter` specializations. + +--- + +## Template parameters + +| Parameter | Description | Default | +| ----------- | ------------------------------------------------------------------------ | ----------- | +| `Rows` | Number of rows (size_t, compile-time) | — | +| `Columns` | Number of columns (size_t, compile-time) | — | +| `Type` | Element type (arithmetic) | `float` | +| `StoreType` | Storage order: `MatStoreType::ROW_MAJOR` or `MatStoreType::COLUMN_MAJOR` | `ROW_MAJOR` | + +```cpp +enum class MatStoreType : uint8_t { ROW_MAJOR = 0, COLUMN_MAJOR }; +``` + +--- + +## Quick start + +```cpp +#include "mat.hpp" +using omath::Mat; + +// 4x4 float, row-major +Mat<4,4> I = { + {1,0,0,0}, + {0,1,0,0}, + {0,0,1,0}, + {0,0,0,1}, +}; + +// Multiply 4x4 transforms +Mat<4,4> A = { {1,2,3,0},{0,1,4,0},{5,6,0,0},{0,0,0,1} }; +Mat<4,4> B = { {2,0,0,0},{0,2,0,0},{0,0,2,0},{0,0,0,1} }; +Mat<4,4> C = A * B; // matrix × matrix + +// Scalar ops +auto D = C * 0.5f; // scale all entries + +// Indexing (C++23 multi-parameter operator[]) +float a03 = A[0,3]; // same as A.at(0,3) +A[1,2] = 42.0f; + +// Transpose, determinant, inverse +auto AT = A.transposed(); +float det = A.determinant(); // only for square matrices +auto inv = A.inverted(); // std::optional; std::nullopt if non-invertible +``` + +> **Note** +> Multiplication requires the **same** `StoreType` and `Type` on both operands, and dimensions must match at compile time. + +--- + +## Construction + +```cpp +Mat(); // zero-initialized +Mat(std::initializer_list> rows); +explicit Mat(const Type* raw_data); // copies Rows*Columns elements +Mat(const Mat&); Mat(Mat&&); +``` + +* **Zeroing/setting** + + ```cpp + m.clear(); // set all entries to 0 + m.set(3.14f); // set all entries to a value + ``` + +* **Shape & metadata** + + ```cpp + Mat<>::row_count(); // constexpr size_t + Mat<>::columns_count(); // constexpr size_t + Mat<>::size(); // constexpr MatSize {rows, columns} + Mat<>::get_store_ordering(); // constexpr MatStoreType + using ContainedType = Type; // alias + ``` + +--- + +## Element access + +```cpp +T& at(size_t r, size_t c); +T const& at(size_t r, size_t c) const; + +T& operator[](size_t r, size_t c); // C++23 +T const& operator[](size_t r, size_t c) const; // C++23 +``` + +> **Bounds checking** +> In debug builds you may enable/disable range checks via your compile-time macros (see the source guard around `at()`). + +--- + +## Arithmetic + +* **Matrix × matrix** + + ```cpp + // (Rows x Columns) * (Columns x OtherColumns) -> (Rows x OtherColumns) + template + Mat + operator*(const Mat&) const; + ``` + + * Complexity: `O(Rows * Columns * OtherColumns)`. + * AVX2-accelerated when `OMATH_USE_AVX2` is defined and `Type` is `float` or `double`. + +* **Scalars** + + ```cpp + Mat operator*(const Type& s) const; Mat& operator*=(const Type& s); + Mat operator/(const Type& s) const; Mat& operator/=(const Type& s); + ``` + +* **Transpose** + + ```cpp + Mat transposed() const noexcept; + ``` + +* **Determinant (square only)** + + ```cpp + Type determinant() const; // 1x1, 2x2 fast path; larger uses Laplace expansion + ``` + +* **Inverse (square only)** + + ```cpp + std::optional inverted() const; // nullopt if det == 0 + ``` + +* **Minors & cofactors (square only)** + + ```cpp + Mat strip(size_t r, size_t c) const; + Type minor(size_t r, size_t c) const; + Type alg_complement(size_t r, size_t c) const; // cofactor + ``` + +* **Utilities** + + ```cpp + Type sum() const noexcept; + auto& raw_array(); // std::array& + auto const& raw_array() const; + ``` + +* **Comparison / formatting** + + ```cpp + bool operator==(const Mat&) const; + bool operator!=(const Mat&) const; + + std::string to_string() const noexcept; + std::wstring to_wstring() const noexcept; + std::u8string to_u8string() const noexcept; + ``` + +// std::formatter specialization provided for char, wchar_t, char8_t + +```` + +--- + +## Storage order notes + +- **Row-major**: `index = row * Columns + column` +- **Column-major**: `index = row + column * Rows` + +Choose one **consistently** across your math types and shader conventions. Mixed orders are supported by the type system but not for cross-multiplying (store types must match). + +--- + +## Transform helpers + +### From vectors + +```cpp +template +Mat<1,4,T,St> mat_row_from_vector(const Vector3& v); + +template +Mat<4,1,T,St> mat_column_from_vector(const Vector3& v); +```` + +### Translation + +```cpp +template +Mat<4,4,T,St> mat_translation(const Vector3& d) noexcept; +``` + +### Axis rotations + +```cpp +// Angle type must provide angle.cos() and angle.sin() +template +Mat<4,4,T,St> mat_rotation_axis_x(const Angle& a) noexcept; + +template +Mat<4,4,T,St> mat_rotation_axis_y(const Angle& a) noexcept; + +template +Mat<4,4,T,St> mat_rotation_axis_z(const Angle& a) noexcept; +``` + +### Camera/view + +```cpp +template +Mat<4,4,T,St> mat_camera_view(const Vector3& forward, + const Vector3& right, + const Vector3& up, + const Vector3& camera_origin) noexcept; +``` + +### Perspective projections + +```cpp +template +Mat<4,4,T,St> mat_perspective_left_handed (float fov_deg, float aspect, float near, float far) noexcept; + +template +Mat<4,4,T,St> mat_perspective_right_handed(float fov_deg, float aspect, float near, float far) noexcept; +``` + +### Orthographic projections + +```cpp +template +Mat<4,4,T,St> mat_ortho_left_handed (T left, T right, T bottom, T top, T near, T far) noexcept; + +template +Mat<4,4,T,St> mat_ortho_right_handed(T left, T right, T bottom, T top, T near, T far) noexcept; +``` + +### Look-at matrices + +```cpp +template +Mat<4,4,T,St> mat_look_at_left_handed (const Vector3& eye, + const Vector3& center, + const Vector3& up); + +template +Mat<4,4,T,St> mat_look_at_right_handed(const Vector3& eye, + const Vector3& center, + const Vector3& up); +``` + +--- + +## Screen-space helper + +```cpp +template +static constexpr Mat<4,4> to_screen_mat(const Type& screen_w, const Type& screen_h) noexcept; +// Maps NDC to screen space (origin top-left, y down) +``` + +--- + +## Examples + +### 1) Building a left-handed camera and perspective + +```cpp +using V3 = omath::Vector3; +using M4 = omath::Mat<4,4,float, omath::MatStoreType::COLUMN_MAJOR>; + +V3 eye{0, 1, -5}, center{0, 0, 0}, up{0, 1, 0}; +M4 view = omath::mat_look_at_left_handed(eye, center, up); + +float fov = 60.f, aspect = 16.f/9.f, n = 0.1f, f = 100.f; +M4 proj = omath::mat_perspective_left_handed(fov, aspect, n, f); + +// final VP +M4 vp = proj * view; +``` + +### 2) Inverting a transform safely + +```cpp +omath::Mat<4,4> T = omath::mat_translation(omath::Vector3{2,3,4}); +if (auto inv = T.inverted()) { + // use *inv +} else { + // handle non-invertible +} +``` + +### 3) Formatting for logs + +```cpp +omath::Mat<2,2> A = { {1,2},{3,4} }; +std::string s = A.to_string(); // "[[ 1.000, 2.000]\n [ 3.000, 4.000]]" +std::string f = std::format("A = {}", A); // uses std::formatter +``` + +--- + +## Performance + +* **Cache-friendly kernels** per storage order when AVX2 is not enabled. +* **AVX2 path** (`OMATH_USE_AVX2`) for `float`/`double` implements FMAs with 256-bit vectors for both row-major and column-major multiplication. +* Complexity for `A(R×K) * B(K×C)`: **O(RKC)** regardless of storage order. + +--- + +## Constraints & concepts + +```cpp +template +concept MatTemplateEqual = + (M1::rows == M2::rows) && + (M1::columns == M2::columns) && + std::is_same_v && + (M1::store_type == M2::store_type); +``` + +> Use this concept to constrain generic functions that operate on like-shaped matrices. + +--- + +## Exceptions + +* `std::invalid_argument` — initializer list dimensions mismatch. +* `std::out_of_range` — out-of-bounds in `at()` when bounds checking is active (see source guard). +* `inverted()` does **not** throw; returns `std::nullopt` if `determinant() == 0`. + +--- + +## Build switches + +* **`OMATH_USE_AVX2`** — enable AVX2 vectorized multiplication paths (`` required). +* **Debug checks** — the `at()` method contains a conditional range check; refer to the preprocessor guard in the code to enable/disable in your configuration. + +--- + +## Known requirements & interoperability + +* **C++23** is required for multi-parameter `operator[]`. If you target pre-C++23, use `at(r,c)` instead. +* All binary operations require matching `Type` and `StoreType`. Convert explicitly if needed. + +--- + +## See also + +* `omath::Vector3` +* Projection helpers: `mat_perspective_*`, `mat_ortho_*` +* View helpers: `mat_look_at_*`, `mat_camera_view` +* Construction helpers: `mat_row_from_vector`, `mat_column_from_vector`, `mat_translation`, `mat_rotation_axis_*` + +--- + +## Appendix: API summary (signatures) + +```cpp +// Core +Mat(); Mat(const Mat&); Mat(Mat&&); +Mat(std::initializer_list>); +explicit Mat(const Type* raw); +Mat& operator=(const Mat&); Mat& operator=(Mat&&); + +static constexpr size_t row_count(); +static constexpr size_t columns_count(); +static consteval MatSize size(); +static constexpr MatStoreType get_store_ordering(); + +T& at(size_t r, size_t c); +T const& at(size_t r, size_t c) const; +T& operator[](size_t r, size_t c); +T const& operator[](size_t r, size_t c) const; + +void clear(); +void set(const Type& v); +Type sum() const noexcept; + +template Mat operator*(const Mat&) const; +Mat& operator*=(const Type&); Mat operator*(const Type&) const; +Mat& operator/=(const Type&); Mat operator/(const Type&) const; + +Mat transposed() const noexcept; +Type determinant() const; // square only +std::optional inverted() const; // square only + +Mat strip(size_t r, size_t c) const; +Type minor(size_t r, size_t c) const; +Type alg_complement(size_t r, size_t c) const; + +auto& raw_array(); auto const& raw_array() const; +std::string to_string() const noexcept; +std::wstring to_wstring() const noexcept; +std::u8string to_u8string() const noexcept; + +bool operator==(const Mat&) const; +bool operator!=(const Mat&) const; + +// Helpers (see sections above) +``` + +--- + +*Last updated: 31 Oct 2025* diff --git a/docs/styles/dark-overrides.css b/docs/styles/dark-overrides.css new file mode 100644 index 0000000..eef24c4 --- /dev/null +++ b/docs/styles/dark-overrides.css @@ -0,0 +1,67 @@ +/* styles/dark-overrides.css */ +:root[data-md-color-scheme="mydark"] { + color-scheme: dark; /* important for native UI */ + --md-default-bg-color: #0d0f12; + --md-code-bg-color: #12151a; + --md-footer-bg-color: #0b0d10; + + --md-default-fg-color: #dfe5ef; + --md-typeset-color: #dfe5ef; + --md-default-fg-color--light: #aab2bf; + --md-code-fg-color: #e6edf3; + + --md-primary-fg-color: #7c4dff; + --md-accent-fg-color: #c6ff00; + + --md-default-fg-color--lighter: #2a2f36; + --md-shadow-z1: 0 2px 6px rgba(0,0,0,.35); +} + +/* Ensure the page chrome actually uses the bg (prevents white flashes/areas) */ +html[data-md-color-scheme="mydark"], +body[data-md-color-scheme="mydark"], +.md-header, .md-main, .md-footer, .md-sidebar { + background-color: #0d0f12 !important; +} + +/* Optional: code tokens */ +:root[data-md-color-scheme="mydark"] .md-typeset code, +:root[data-md-color-scheme="mydark"] .md-typeset pre { + --md-code-hl-keyword-color: #c678dd; + --md-code-hl-string-color: #98c379; + --md-code-hl-name-color: #61afef; + --md-code-hl-number-color: #d19a66; +} +/* Make default/body text white-ish in dark mode */ +:root[data-md-color-scheme="mydark"] { + --md-default-fg-color: #e6edf3; /* global text */ + --md-default-fg-color--light: #c5cfdb; + --md-default-fg-color--lighter: #9aa4b2; + --md-typeset-color: #e6edf3; /* content text */ +} + +/* Ensure it actually applies (beats theme selectors) */ +:root[data-md-color-scheme="mydark"] body, +:root[data-md-color-scheme="mydark"] .md-content, +:root[data-md-color-scheme="mydark"] .md-typeset { + color: var(--md-typeset-color) !important; +} + +/* Nav, header, footer text */ +:root[data-md-color-scheme="mydark"] .md-header, +:root[data-md-color-scheme="mydark"] .md-footer, +:root[data-md-color-scheme="mydark"] .md-nav, +:root[data-md-color-scheme="mydark"] .md-nav__link { + color: var(--md-default-fg-color) !important; +} + +/* Link color in articles (optional) */ +:root[data-md-color-scheme="mydark"] .md-typeset a { + color: var(--md-accent-fg-color); +} + +/* Inline code text (optional) */ +:root[data-md-color-scheme="mydark"] code, +:root[data-md-color-scheme="mydark"] pre { + color: var(--md-code-fg-color) !important; +} diff --git a/mkdocs.yml b/mkdocs.yml index c97182f..91c36ad 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1 +1,3 @@ -site_name: My Docs +site_name: OM Docs +theme: + name: darkly \ No newline at end of file