diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..a3f36ab --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,92 @@ +## Goal + +My goal is to provide a space where it is safe for everyone to contribute to, +and get support for, open-source software in a respectful and cooperative +manner. + +I value all contributions and want to make this project and its +surrounding community a place for everyone. + +As members, contributors, and everyone else who may participate in the +development, I strive to keep the entire experience civil. + +## Standards + +Our community standards exist in order to make sure everyone feels comfortable +contributing to the project(s) together. + +Our standards are: +- Do not harass, attack, or in any other way discriminate against anyone, including + for their protected traits, including, but not limited to, sex, religion, race, + appearance, gender, identity, nationality, sexuality, etc. +- Do not go off-topic, do not post spam. +- Treat everyone with respect. + +Examples of breaking each rule respectively include: +- Harassment, bullying or inappropriate jokes about another person. +- Posting distasteful imagery, trolling, or posting things unrelated to the topic at hand. +- Treating someone as worse because of their lack of understanding of an issue. + +## Enforcement + +Enforcement of this CoC is done by Orange++ and/or other core contributors. + +I, as the core developer, will strive my best to keep this community civil and +following the standards outlined above. + +### Reporting incidents + +If you believe an incident of breaking these standards has occurred, but nobody has +taken appropriate action, you can privately contact the people responsible for dealing +with such incidents in multiple ways: + +***E-Mail*** +- `orange-cpp@yandex.ru` + +***Discord*** +- `@orange_cpp` + +***Telegram*** +- `@orange-cpp` +I guarantee your privacy and will not share those reports with anyone. + +## Enforcement Strategy + +Depending on the severity of the infraction, any action from the list below may be applied. +Please keep in mind cases are reviewed on a per-case basis and members are the ultimate +deciding factor in the type of punishment. + +If the matter benefited from an outside opinion, a member might reach for more opinions +from people unrelated, however, the final decision regarding the action +to be taken is still up to the member. + +For example, if the matter at hand regards a representative of a marginalized group or minority, +the member might ask for a first-hand opinion from another representative of such group. + +### Correction/Edit + +If your message is found to be misleading or poorly worded, a member might +edit your message. + +### Warning/Deletion + +If your message is found inappropriate, a member might give you a public or private warning, +and/or delete your message. + +### Mute + +If your message is disruptive, or you have been repeatedly violating the standards, +a member might mute (or temporarily ban) you. + +### Ban + +If your message is hateful, very disruptive, or other, less serious infractions are repeated +ignoring previous punishments, a member might ban you permanently. + +## Scope + +This CoC shall apply to all projects ran under the Orange++ lead and all _official_ communities +outside of GitHub. + +However, it is worth noting that official communities outside of GitHub might have their own, +additional sets of rules. \ No newline at end of file diff --git a/readme.md b/README.md similarity index 82% rename from readme.md rename to README.md index 07bb7c4..4fca58d 100644 --- a/readme.md +++ b/README.md @@ -17,6 +17,8 @@ Oranges's Math Library (omath) is a comprehensive, open-source library aimed at - **Ease of Use**: Simplified interface for convenient integration into various projects. - **Projectile Prediction**: Projectile prediction engine with O(N) algo complexity, that can power you projectile aim-bot. - **3D Projection**: No need to find view-projection matrix anymore you can make your own projection pipeline. +- **Collision Detection**: Production ready code to handle collision detection by using simple interfaces. +- **No Additional Dependencies**: No additional dependencies need to use OMath except unit test execution ## Getting Started ### Prerequisites @@ -34,10 +36,10 @@ Oranges's Math Library (omath) is a comprehensive, open-source library aimed at ``` 3. Build the project using CMake: ``` - cmake --preset x64-release -S . - cmake --build cmake-build/build/x64-release --target server -j 6 + cmake --preset windows-release -S . + cmake --build cmake-build/build/windows-release --target server -j 6 ``` - + Use **\-\** preset to build siutable version for yourself. Like **windows-release** or **linux-release**. ## Usage Simple world to screen function ```c++ @@ -64,7 +66,7 @@ With `omath/projection` module you can achieve simple ESP hack for powered by So Contributions to `omath` are welcome! Please read `CONTRIBUTING.md` for details on our code of conduct and the process for submitting pull requests. ## License -This project is licensed under the GPL V3 - see the `LICENSE` file for details. +This project is licensed under the MIT - see the `LICENSE` file for details. ## Acknowledgments - Orange | [Telegram](https://t.me/orange_cpp) diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..190b1a5 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,5 @@ +# Security Policy + +## Reporting a Vulnerability + +Please report security issues to `orange-cpp@yandex.com` \ No newline at end of file diff --git a/include/omath/Triangle3d.hpp b/include/omath/Triangle3d.hpp new file mode 100644 index 0000000..f755ebf --- /dev/null +++ b/include/omath/Triangle3d.hpp @@ -0,0 +1,32 @@ +// +// Created by Orange on 11/13/2024. +// +#pragma once +#include "omath/Vector3.hpp" + +namespace omath +{ + class Triangle3d final + { + public: + Triangle3d(const Vector3& vertex1, const Vector3& vertex2, const Vector3& vertex3); + Vector3 m_vertex1; + Vector3 m_vertex2; + Vector3 m_vertex3; + + [[nodiscard]] + Vector3 CalculateNormal() const; + + [[nodiscard]] + float SideALength() const; + + [[nodiscard]] + float SideBLength() const; + + [[nodiscard]] + Vector3 SideAVector() const; + + [[nodiscard]] + Vector3 SideBVector() const; + }; +} \ No newline at end of file diff --git a/include/omath/collision/LineTracer.hpp b/include/omath/collision/LineTracer.hpp new file mode 100644 index 0000000..1de6d1e --- /dev/null +++ b/include/omath/collision/LineTracer.hpp @@ -0,0 +1,38 @@ +// +// Created by Orange on 11/13/2024. +// +#pragma once + +#include "omath/Vector3.hpp" +#include "omath/Triangle3d.hpp" + + +namespace omath::collision +{ + class Ray + { + public: + Vector3 start; + Vector3 end; + + [[nodiscard]] + Vector3 DirectionVector() const; + + [[nodiscard]] + Vector3 DirectionVectorNormalized() const; + }; + class LineTracer + { + public: + LineTracer() = delete; + + [[nodiscard]] + static bool CanTraceLine(const Ray& ray, const Triangle3d& triangle); + + + // Realization of Möller–Trumbore intersection algorithm + // https://en.wikipedia.org/wiki/M%C3%B6ller%E2%80%93Trumbore_intersection_algorithm + [[nodiscard]] + static Vector3 GetRayHitPoint(const Ray& ray, const Triangle3d& triangle); + }; +} diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 9d79f16..ab4e824 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -3,8 +3,11 @@ target_sources(omath PRIVATE Matrix.cpp color.cpp Vector4.cpp - Vector2.cpp) + Vector2.cpp + Triangle3d.cpp +) add_subdirectory(prediction) add_subdirectory(pathfinding) -add_subdirectory(projection) \ No newline at end of file +add_subdirectory(projection) +add_subdirectory(collision) \ No newline at end of file diff --git a/source/Triangle3d.cpp b/source/Triangle3d.cpp new file mode 100644 index 0000000..54dcf75 --- /dev/null +++ b/source/Triangle3d.cpp @@ -0,0 +1,36 @@ +#include "omath/Triangle3d.hpp" + + +namespace omath +{ + Triangle3d::Triangle3d(const Vector3 &vertex1, const Vector3 &vertex2, const Vector3 &vertex3) + : m_vertex1(vertex1), m_vertex2(vertex2), m_vertex3(vertex3) + { + + } + + Vector3 Triangle3d::CalculateNormal() const + { + return (m_vertex1 - m_vertex2).Cross(m_vertex3 - m_vertex1).Normalized(); + } + + float Triangle3d::SideALength() const + { + return m_vertex1.DistTo(m_vertex2); + } + + float Triangle3d::SideBLength() const + { + return m_vertex3.DistTo(m_vertex2); + } + + Vector3 Triangle3d::SideAVector() const + { + return m_vertex1 - m_vertex2; + } + + Vector3 Triangle3d::SideBVector() const + { + return m_vertex3 - m_vertex2; + } +} diff --git a/source/collision/CMakeLists.txt b/source/collision/CMakeLists.txt new file mode 100644 index 0000000..22a2abc --- /dev/null +++ b/source/collision/CMakeLists.txt @@ -0,0 +1,3 @@ +target_sources(omath PRIVATE + LineTracer.cpp +) diff --git a/source/collision/LineTracer.cpp b/source/collision/LineTracer.cpp new file mode 100644 index 0000000..905350b --- /dev/null +++ b/source/collision/LineTracer.cpp @@ -0,0 +1,63 @@ +// +// Created by Orange on 11/13/2024. +// +#pragma once +#include "omath/collision/LineTracer.hpp" + +namespace omath::collision +{ + bool LineTracer::CanTraceLine(const Ray &ray, const Triangle3d &triangle) + { + return GetRayHitPoint(ray, triangle) == ray.end; + } + Vector3 Ray::DirectionVector() const + { + return end - start; + } + + Vector3 Ray::DirectionVectorNormalized() const + { + return DirectionVector().Normalized(); + } + + Vector3 LineTracer::GetRayHitPoint(const Ray &ray, const Triangle3d &triangle) + { + constexpr float kEpsilon = std::numeric_limits::epsilon(); + + const auto sideA = triangle.SideAVector(); + const auto sideB = triangle.SideBVector(); + + + const auto rayDir = ray.DirectionVector(); + + const auto p = rayDir.Cross(sideB); + const auto det = sideA.Dot(p); + + + if (std::abs(det) < kEpsilon) + return ray.end; + + const auto invDet = 1.0f / det; + const auto t = ray.start - triangle.m_vertex2; + const auto u = t.Dot(p) * invDet; + + + if ((u < 0 && std::abs(u) > kEpsilon) || (u > 1 && std::abs(u-1) > kEpsilon)) + return ray.end; + + const auto q = t.Cross(sideA); + const auto v = rayDir.Dot(q) * invDet; + + + if ((v < 0 && std::abs(v) > kEpsilon) || (u + v > 1 && std::abs(u + v - 1) > kEpsilon)) + return ray.end; + + const auto tHit = sideB.Dot(q) * invDet; + + + if (tHit <= kEpsilon) + return ray.end; + + return ray.start + rayDir * tHit; + } +} diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 90f0bea..1c604c1 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -13,7 +13,9 @@ add_executable(unit-tests UnitTestVector3.cpp UnitTestVector2.cpp UnitTestColor.cpp - UnitTestVector4.cpp) + UnitTestVector4.cpp + UnitTestLineTrace.cpp +) target_link_libraries(unit-tests PRIVATE gtest gtest_main omath) diff --git a/tests/UnitTestLineTrace.cpp b/tests/UnitTestLineTrace.cpp new file mode 100644 index 0000000..67884d9 --- /dev/null +++ b/tests/UnitTestLineTrace.cpp @@ -0,0 +1,80 @@ +#include "gtest/gtest.h" +#include "omath/collision/LineTracer.hpp" +#include "omath/Triangle3d.hpp" +#include "omath/Vector3.hpp" + +using namespace omath; +using namespace omath::collision; + +class LineTracerTest : public ::testing::Test +{ +protected: + // Set up common variables for use in each test + Vector3 vertex1{0.0f, 0.0f, 0.0f}; + Vector3 vertex2{1.0f, 0.0f, 0.0f}; + Vector3 vertex3{0.0f, 1.0f, 0.0f}; + Triangle3d triangle{vertex1, vertex2, vertex3}; +}; + +// Test that a ray intersecting the triangle returns false for CanTraceLine +TEST_F(LineTracerTest, RayIntersectsTriangle) +{ + constexpr Ray ray{{0.3f, 0.3f, -1.0f}, {0.3f, 0.3f, 1.0f}}; + EXPECT_FALSE(LineTracer::CanTraceLine(ray, triangle)); +} + +// Test that a ray parallel to the triangle plane returns true for CanTraceLine +TEST_F(LineTracerTest, RayParallelToTriangle) +{ + constexpr Ray ray{{0.3f, 0.3f, 1.0f}, {0.3f, 0.3f, 2.0f}}; + EXPECT_TRUE(LineTracer::CanTraceLine(ray, triangle)); +} + +// Test that a ray starting inside the triangle but pointing away returns true +TEST_F(LineTracerTest, RayStartsInTriangleButDoesNotIntersect) +{ + constexpr Ray ray{{0.3f, 0.3f, 0.0f}, {0.3f, 0.3f, -1.0f}}; + EXPECT_TRUE(LineTracer::CanTraceLine(ray, triangle)); +} + +// Test that a ray not intersecting the triangle plane returns true +TEST_F(LineTracerTest, RayMissesTriangle) +{ + constexpr Ray ray{{2.0f, 2.0f, -1.0f}, {2.0f, 2.0f, 1.0f}}; + EXPECT_TRUE(LineTracer::CanTraceLine(ray, triangle)); +} + +// Test that a ray lying exactly in the plane of the triangle without intersecting returns true +TEST_F(LineTracerTest, RayInPlaneNotIntersecting) +{ + constexpr Ray ray{{-1.0f, -1.0f, 0.0f}, {1.5f, 1.5f, 0.0f}}; + EXPECT_TRUE(LineTracer::CanTraceLine(ray, triangle)); +} + + +TEST_F(LineTracerTest, RayIntersectsVertex) +{ + const Ray ray{{-1.0f, -1.0f, -1.0f}, vertex1}; // Intersecting at vertex1 + EXPECT_TRUE(LineTracer::CanTraceLine(ray, triangle)); +} + +TEST_F(LineTracerTest, RayIntersectsEdge) +{ + constexpr Ray ray{{-1.0f, 0.0f, -1.0f}, {0.5f, 0.0f, 0.0f}}; + // Intersecting on the edge between vertex1 and vertex2 + EXPECT_TRUE(LineTracer::CanTraceLine(ray, triangle)); +} + +TEST_F(LineTracerTest, TriangleFarBeyondRayEndPoint) +{ + // Define a ray with a short length + constexpr Ray ray{{0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 1.0f}}; + + // Define a triangle far beyond the ray's endpoint + const Triangle3d distantTriangle{ + {1000.0f, 1000.0f, 1000.0f}, {1001.0f, 1000.0f, 1000.0f}, {1000.0f, 1001.0f, 1000.0f} + }; + + // Expect true because the ray ends long before it could reach the distant triangle + EXPECT_TRUE(LineTracer::CanTraceLine(ray, distantTriangle)); +}