Compare commits

..

10 Commits

Author SHA1 Message Date
646a920e4c fixed potential deadlock 2026-02-27 08:47:46 +03:00
52687a70c7 fixed formating 2026-02-27 07:41:05 +03:00
a9eff7d320 Merge pull request #157 from orange-cpp/feature/mesh_improvement
Feature/mesh improvement
2026-02-26 16:39:21 +03:00
211e4c3d9b optimization 2026-02-26 16:19:54 +03:00
74dc2234f7 fixed collider when rotated 2026-02-26 16:17:41 +03:00
7ebbed6763 added funding
edit
2026-02-23 07:18:25 +03:00
e271bccaf5 added codeowners 2026-02-23 06:45:43 +03:00
50765f69c5 removed unused var 2026-02-23 04:36:48 +03:00
1169534133 fix 2026-02-23 04:32:13 +03:00
783501aab9 Enhance installation guide with prebuilt binaries section
Updated vcpkg section and added instructions for using prebuilt binaries from GitHub Releases.
2026-02-21 10:00:19 +03:00
6 changed files with 113 additions and 16 deletions

4
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1,4 @@
# These are supported funding model platforms
open_collective: libomathorg
github: orange-cpp

37
CODEOWNERS Normal file
View File

@@ -0,0 +1,37 @@
## List of maintainers for the omath library
## This file purpose is to give newcomers to the project the responsible
## developers when submitting a pull request on GitHub, or opening a bug
## report in issues.
## This file will notably establish who is responsible for a specific
## area of omath. Being a maintainer means the following:
## - that person has good knownledge in the area
## - that person is able to enforce consistency in the area
## - that person may be available for giving help in the area
## - that person has push access on the repository
## Being a maintainer does not mean the following:
## - that person is dedicated to the area
## - that person is working full-time on the area/on omath
## - that person is paid
## - that person is always available
# omath core source code
/source @orange-cpp
/include @orange-cpp
# Tests and becnchmarks
/benchmark @orange-cpp
/tests @orange-cpp @luadebug
# Examples and documentation
/examples @luadebug @orange-cpp
/docs @orange-cpp
# Misc like formating
/scripts @luadebug
/pixi @luadebug
# CI/CD
/.github/workflows @luadbg @orange-cpp

View File

@@ -1,6 +1,6 @@
# 📥Installation Guide # 📥Installation Guide
## <img width="28px" src="https://vcpkg.io/assets/mark/mark.svg" /> Using vcpkg ## <img width="28px" src="https://vcpkg.io/assets/mark/mark.svg" /> Using vcpkg (recomended)
**Note**: Support vcpkg for package management **Note**: Support vcpkg for package management
1. Install [vcpkg](https://github.com/microsoft/vcpkg) 1. Install [vcpkg](https://github.com/microsoft/vcpkg)
2. Run the following command to install the orange-math package: 2. Run the following command to install the orange-math package:
@@ -28,6 +28,46 @@ target("...")
add_packages("omath") add_packages("omath")
``` ```
## <img width="28px" src="https://github.githubassets.com/favicons/favicon.svg" /> Using prebuilt binaries (GitHub Releases)
**Note**: This is the fastest option if you dont want to build from source.
1. **Go to the Releases page**
- Open the projects GitHub **Releases** page and choose the latest version.
2. **Download the correct asset for your platform**
- Pick the archive that matches your OS and architecture (for example: Windows x64 / Linux x64 / macOS arm64).
3. **Extract the archive**
- You should end up with something like:
- `include/` (headers)
- `lib/` or `bin/` (library files / DLLs)
- sometimes `cmake/` (CMake package config)
4. **Use it in your project**
### Option A: CMake package (recommended if the release includes CMake config files)
If the extracted folder contains something like `lib/cmake/omath` or `cmake/omath`, you can point CMake to it:
```cmake
# Example: set this to the extracted prebuilt folder
list(APPEND CMAKE_PREFIX_PATH "path/to/omath-prebuilt")
find_package(omath CONFIG REQUIRED)
target_link_libraries(main PRIVATE omath::omath)
```
### Option B: Manual include + link (works with any layout)
If theres no CMake package config, link it manually:
```cmake
target_include_directories(main PRIVATE "path/to/omath-prebuilt/include")
# Choose ONE depending on what you downloaded:
# - Static library: .lib / .a
# - Shared library: .dll + .lib import (Windows), .so (Linux), .dylib (macOS)
target_link_directories(main PRIVATE "path/to/omath-prebuilt/lib")
target_link_libraries(main PRIVATE omath) # or the actual library filename
```
## <img width="28px" src="https://upload.wikimedia.org/wikipedia/commons/e/ef/CMake_logo.svg?" /> Build from source using CMake ## <img width="28px" src="https://upload.wikimedia.org/wikipedia/commons/e/ef/CMake_logo.svg?" /> Build from source using CMake
1. **Preparation** 1. **Preparation**

View File

@@ -14,11 +14,15 @@ namespace omath::collision
Simplex<VertexType> simplex; // valid only if hit == true and size==4 Simplex<VertexType> simplex; // valid only if hit == true and size==4
}; };
struct GjkSettings final
{
float epsilon = 1e-6f;
std::size_t max_iterations = 64;
};
template<class ColliderInterfaceType> template<class ColliderInterfaceType>
class GjkAlgorithm final class GjkAlgorithm final
{ {
using VectorType = ColliderInterfaceType::VectorType; using VectorType = ColliderInterfaceType::VectorType;
public: public:
[[nodiscard]] [[nodiscard]]
static VectorType find_support_vertex(const ColliderInterfaceType& collider_a, static VectorType find_support_vertex(const ColliderInterfaceType& collider_a,
@@ -36,7 +40,8 @@ namespace omath::collision
[[nodiscard]] [[nodiscard]]
static GjkHitInfo<VectorType> is_collide_with_simplex_info(const ColliderInterfaceType& collider_a, static GjkHitInfo<VectorType> is_collide_with_simplex_info(const ColliderInterfaceType& collider_a,
const ColliderInterfaceType& collider_b) const ColliderInterfaceType& collider_b,
const GjkSettings& settings = {})
{ {
auto support = find_support_vertex(collider_a, collider_b, VectorType{1, 0, 0}); auto support = find_support_vertex(collider_a, collider_b, VectorType{1, 0, 0});
@@ -45,11 +50,11 @@ namespace omath::collision
auto direction = -support; auto direction = -support;
while (true) for (std::size_t iteration = 0; iteration < settings.max_iterations; ++iteration)
{ {
support = find_support_vertex(collider_a, collider_b, direction); support = find_support_vertex(collider_a, collider_b, direction);
if (support.dot(direction) <= 0.f) if (support.dot(direction) <= settings.epsilon)
return {false, simplex}; return {false, simplex};
simplex.push_front(support); simplex.push_front(support);
@@ -57,6 +62,7 @@ namespace omath::collision
if (simplex.handle(direction)) if (simplex.handle(direction))
return {true, simplex}; return {true, simplex};
} }
return {false, simplex};
} }
}; };
} // namespace omath::collision } // namespace omath::collision

View File

@@ -46,9 +46,26 @@ namespace omath::collision
[[nodiscard]] [[nodiscard]]
const VertexType& find_furthest_vertex(const VectorType& direction) const const VertexType& find_furthest_vertex(const VectorType& direction) const
{ {
return *std::ranges::max_element( // The support query arrives in world space, but vertex positions are stored
m_mesh.m_vertex_buffer, [&direction](const auto& first, const auto& second) // in local space. We need argmax_v { world(v) · d }.
{ return first.position.dot(direction) < second.position.dot(direction); }); //
// world(v) = M·v (ignoring translation, which is constant across vertices)
// world(v) · d = v · Mᵀ·d
//
// So we transform the direction to local space once — O(1) — then compare
// raw local positions, which is far cheaper than calling
// vertex_position_to_world_space (full 4×4 multiply) for every vertex.
//
// d_local = upper-left 3×3 of M, transposed, times d_world:
// d_local[j] = sum_i M.at(i,j) * d[i] (i.e. column j of M dotted with d)
const auto& m = m_mesh.get_to_world_matrix();
const VectorType d_local = {
m[0, 0] * direction.x + m[1, 0] * direction.y + m[2, 0] * direction.z,
m[0, 1] * direction.x + m[1, 1] * direction.y + m[2, 1] * direction.z,
m[0, 2] * direction.x + m[1, 2] * direction.y + m[2, 2] * direction.z,
};
return *std::ranges::max_element(m_mesh.m_vertex_buffer, [&d_local](const auto& first, const auto& second)
{ return first.position.dot(d_local) < second.position.dot(d_local); });
} }
MeshType m_mesh; MeshType m_mesh;
}; };

View File

@@ -62,20 +62,13 @@ namespace omath::detail
return splitmix64(base_seed() + 0xD1B54A32D192ED03ull * (Stream + 1)); return splitmix64(base_seed() + 0xD1B54A32D192ED03ull * (Stream + 1));
} }
[[nodiscard]]
consteval std::uint64_t bounded_u64(const std::uint64_t x, const std::uint64_t bound)
{
return (x * bound) >> 64;
}
template<std::int64_t Lo, std::int64_t Hi, std::uint64_t Stream> template<std::int64_t Lo, std::int64_t Hi, std::uint64_t Stream>
[[nodiscard]] [[nodiscard]]
consteval std::int64_t rand_uint8_t() consteval std::int64_t rand_uint8_t()
{ {
static_assert(Lo <= Hi); static_assert(Lo <= Hi);
const std::uint64_t span = static_cast<std::uint64_t>(Hi - Lo) + 1ull;
const std::uint64_t r = rand_u64<Stream>(); const std::uint64_t r = rand_u64<Stream>();
return static_cast<std::int64_t>(bounded_u64(r, span)) + Lo; return static_cast<std::int64_t>(r) + Lo;
} }
[[nodiscard]] [[nodiscard]]
consteval std::uint64_t rand_u64(const std::uint64_t seed, const std::uint64_t i) consteval std::uint64_t rand_u64(const std::uint64_t seed, const std::uint64_t i)