Skip to content

Commit

Permalink
Add colliders implementations
Browse files Browse the repository at this point in the history
Defines several colliders that can be used and
between which the collision occurring can be checked
  • Loading branch information
Notiooo committed Dec 14, 2023
1 parent 5271ebe commit 1c4ba5e
Show file tree
Hide file tree
Showing 9 changed files with 337 additions and 0 deletions.
4 changes: 4 additions & 0 deletions AimGL/src/CMakeLists_Sources.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,9 @@ set(PROJECT_SOURCES
World/Scene/GameObjects/Rifle.cpp
World/Physics/Collider.cpp
World/Physics/ColliderRegister.cpp
World/Physics/RayCollider.cpp
World/Physics/RectangleCollider.cpp
World/Physics/SphereCollider.cpp
World/Physics/Collisions.cpp
Utils/Mouse.cpp
)
53 changes: 53 additions & 0 deletions AimGL/src/World/Physics/Collisions.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#include "Collisions.h"
#include "pch.h"

#include "World/Physics/RayCollider.h"
#include "World/Physics/RectangleCollider.h"
#include "World/Physics/SphereCollider.h"

bool checkSphereRectangleCollision(const SphereCollider& sphere, const RectangleCollider& rectangle)
{
glm::vec3 closestPoint = glm::clamp(sphere.center, rectangle.min, rectangle.max);
float distanceSquared = glm::distance(sphere.center, closestPoint);
return distanceSquared < (sphere.radius * sphere.radius);
}

bool checkRaySphereCollision(const RayCollider& ray, const SphereCollider& sphere)
{
// TODO: This Ray-Sphere Collision
return false;
}

bool checkRayRectangleCollision(const RayCollider& ray, const RectangleCollider& rectangle)
{
float tMin = 0.0f;
float tMax = ray.length;

for (int i = 0; i < 3; ++i)
{
if (std::abs(ray.direction[i]) < std::numeric_limits<float>::epsilon())
{
if (ray.origin[i] < rectangle.min[i] || ray.origin[i] > rectangle.max[i])
{
return false;
}
}
else
{
float ood = 1.0f / ray.direction[i];
float t1 = (rectangle.min[i] - ray.origin[i]) * ood;
float t2 = (rectangle.max[i] - ray.origin[i]) * ood;
if (t1 > t2)
{
std::swap(t1, t2);
}
tMin = std::max(tMin, t1);
tMax = std::min(tMax, t2);
if (tMin > tMax)
{
return false;
}
}
}
return tMin <= ray.length;
}
31 changes: 31 additions & 0 deletions AimGL/src/World/Physics/Collisions.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#pragma once


class SphereCollider;
class RectangleCollider;
class RayCollider;

/**
* \brief Checks for collision between a sphere and a rectangle.
* \param sphere The SphereCollider to check for collision.
* \param rectangle The RectangleCollider to check against.
* \return True if there is a collision between the sphere and rectangle, false otherwise.
*/
bool checkSphereRectangleCollision(const SphereCollider& sphere,
const RectangleCollider& rectangle);

/**
* \brief Checks for collision between a ray and a rectangle.
* \param ray The RayCollider to check for collision.
* \param rectangle The RectangleCollider to check against.
* \return True if the ray collides with the rectangle, false otherwise.
*/
bool checkRayRectangleCollision(const RayCollider& ray, const RectangleCollider& rectangle);

/**
* \brief Checks for collision between a ray and a sphere.
* \param ray The RayCollider to check for collision.
* \param sphere The SphereCollider to check against.
* \return True if the ray collides with the sphere, false otherwise.
*/
bool checkRaySphereCollision(const RayCollider& ray, const SphereCollider& sphere);
33 changes: 33 additions & 0 deletions AimGL/src/World/Physics/RayCollider.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#include "RayCollider.h"
#include "World/Physics/Collisions.h"
#include "pch.h"

RayCollider::RayCollider(ColliderRegister& colliderRegister, const glm::vec3& origin,
const glm::vec3& direction, float length)
: Collider(colliderRegister)
, origin(origin)
, direction(glm::normalize(direction))
, length(length)
{
}

bool RayCollider::checkCollision(const Collider& other) const
{
return other.checkCollisionWith(*this);
}

bool RayCollider::checkCollisionWith(const SphereCollider& other) const
{
return checkRaySphereCollision(*this, other);
}

bool RayCollider::checkCollisionWith(const RectangleCollider& other) const
{
return checkRayRectangleCollision(*this, other);
}

bool RayCollider::checkCollisionWith(const RayCollider& other) const
{
// TODO: (anyway I guess I won't need this :D)
return false;
}
51 changes: 51 additions & 0 deletions AimGL/src/World/Physics/RayCollider.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#pragma once
#include "Collider.h"

/**
* \brief A ray that allows to check collisions between other types of colliders
*/
class RayCollider : public Collider
{
public:
/**
* \brief Constructs a Ray object.
* \param colliderRegister Reference to the collision register for tracking this collider.
* \param origin The starting point of the ray in 3D space.
* \param direction The direction vector of the ray. This vector should be normalized.
* \param length (Optional) The length of the ray. Default is 100 units.
*/
RayCollider(ColliderRegister& colliderRegister, const glm::vec3& origin,
const glm::vec3& direction, float length = 100);

/**
* \brief Checks for collision with another collider.
* \param other The collider to check collision against.
* \return True if there is a collision, false otherwise.
*/
[[nodiscard]] bool checkCollision(const Collider& other) const override;

/**
* \brief Checks for collision with a SphereCollider.
* \param other The SphereCollider to check collision against.
* \return True if there is a collision, false otherwise.
*/
[[nodiscard]] bool checkCollisionWith(const SphereCollider& other) const override;

/**
* \brief Checks for collision with a RectangleCollider.
* \param other The RectangleCollider to check collision against.
* \return True if there is a collision, false otherwise.
*/
[[nodiscard]] bool checkCollisionWith(const RectangleCollider& other) const override;

/**
* \brief Checks for collision with another RayCollider.
* \param other The RayCollider to check collision against.
* \return True if there is a collision, false otherwise.
*/
[[nodiscard]] bool checkCollisionWith(const RayCollider& other) const override;

glm::vec3 origin;
glm::vec3 direction;
float length;
};
34 changes: 34 additions & 0 deletions AimGL/src/World/Physics/RectangleCollider.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#include "RectangleCollider.h"

#include "World/Physics/Collisions.h"
#include "pch.h"

RectangleCollider::RectangleCollider(ColliderRegister& colliderRegister, const glm::vec3& min,
const glm::vec3& max)
: Collider(colliderRegister)
, min(min)
, max(max)
{
}

bool RectangleCollider::checkCollision(const Collider& other) const
{
return other.checkCollisionWith(*this);
}

bool RectangleCollider::checkCollisionWith(const SphereCollider& other) const
{
return checkSphereRectangleCollision(other, *this);
}

bool RectangleCollider::checkCollisionWith(const RectangleCollider& other) const
{
return (min.x <= other.max.x && max.x >= other.min.x) &&
(min.y <= other.max.y && max.y >= other.min.y) &&
(min.z <= other.max.z && max.z >= other.min.z);
}

bool RectangleCollider::checkCollisionWith(const RayCollider& other) const
{
return checkRayRectangleCollision(other, *this);
}
49 changes: 49 additions & 0 deletions AimGL/src/World/Physics/RectangleCollider.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#pragma once
#include "Collider.h"

/**
* \brief Represents a rectangle-shaped collider for collision detection.
*/
class RectangleCollider : public Collider
{
public:
/**
* \brief Constructs a RectangleCollider object.
* \param colliderRegister Reference to the collision register for tracking this collider.
* \param min The minimum corner point of the rectangle in 3D space.
* \param max The maximum corner point of the rectangle in 3D space.
*/
RectangleCollider(ColliderRegister& colliderRegister, const glm::vec3& min,
const glm::vec3& max);

/**
* \brief Checks for collision with another collider.
* \param other The collider to check collision against.
* \return True if there is a collision, false otherwise.
*/
[[nodiscard]] bool checkCollision(const Collider& other) const override;

/**
* \brief Checks for collision with a SphereCollider.
* \param other The SphereCollider to check collision against.
* \return True if there is a collision, false otherwise.
*/
[[nodiscard]] bool checkCollisionWith(const SphereCollider& other) const override;

/**
* \brief Checks for collision with another RectangleCollider.
* \param other The RectangleCollider to check collision against.
* \return True if there is a collision, false otherwise.
*/
[[nodiscard]] bool checkCollisionWith(const RectangleCollider& other) const override;

/**
* \brief Checks for collision with a RayCollider.
* \param other The RayCollider to check collision against.
* \return True if there is a collision, false otherwise.
*/
[[nodiscard]] bool checkCollisionWith(const RayCollider& other) const override;

glm::vec3 min;
glm::vec3 max;
};
34 changes: 34 additions & 0 deletions AimGL/src/World/Physics/SphereCollider.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#include "SphereCollider.h"

#include "World/Physics/Collisions.h"
#include "pch.h"

SphereCollider::SphereCollider(ColliderRegister& colliderRegister, const glm::vec3& center,
float radius)
: Collider(colliderRegister)
, center(center)
, radius(radius)
{
}

bool SphereCollider::checkCollision(const Collider& other) const
{
return other.checkCollisionWith(*this);
}

bool SphereCollider::checkCollisionWith(const SphereCollider& other) const
{
float distanceSquared = glm::distance(center, other.center);
float radiusSum = radius + other.radius;
return distanceSquared < (radiusSum * radiusSum);
}

bool SphereCollider::checkCollisionWith(const RectangleCollider& other) const
{
return checkSphereRectangleCollision(*this, other);
}

bool SphereCollider::checkCollisionWith(const RayCollider& other) const
{
return checkRaySphereCollision(other, *this);
}
48 changes: 48 additions & 0 deletions AimGL/src/World/Physics/SphereCollider.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#pragma once
#include "Collider.h"

/**
* \brief Represents a sphere-shaped collider for collision detection.
*/
class SphereCollider : public Collider
{
public:
/**
* \brief Constructs a SphereCollider object.
* \param colliderRegister Reference to the collision register for tracking this collider.
* \param center The center point of the sphere in 3D space.
* \param radius The radius of the sphere.
*/
SphereCollider(ColliderRegister& colliderRegister, const glm::vec3& center, float radius);

/**
* \brief Checks for collision with another collider.
* \param other The collider to check collision against.
* \return True if there is a collision, false otherwise.
*/
[[nodiscard]] bool checkCollision(const Collider& other) const override;

/**
* \brief Checks for collision with a SphereCollider.
* \param other The SphereCollider to check collision against.
* \return True if there is a collision, false otherwise.
*/
[[nodiscard]] bool checkCollisionWith(const SphereCollider& other) const override;

/**
* \brief Checks for collision with another RectangleCollider.
* \param other The RectangleCollider to check collision against.
* \return True if there is a collision, false otherwise.
*/
[[nodiscard]] bool checkCollisionWith(const RectangleCollider& other) const override;

/**
* \brief Checks for collision with a RayCollider.
* \param other The RayCollider to check collision against.
* \return True if there is a collision, false otherwise.
*/
[[nodiscard]] bool checkCollisionWith(const RayCollider& other) const override;

glm::vec3 center;
float radius;
};

0 comments on commit 1c4ba5e

Please sign in to comment.