Skip to content

Commit

Permalink
Add drawable colliders of AABB and ray
Browse files Browse the repository at this point in the history
Adds implementations of drawable colliders, which,
in addition to acting like a collider, also have
their own graphical representation
  • Loading branch information
Notiooo committed Dec 14, 2023
1 parent 1c4ba5e commit 2e215cb
Show file tree
Hide file tree
Showing 10 changed files with 294 additions and 1 deletion.
8 changes: 8 additions & 0 deletions AimGL/resources/Shaders/Graphics/Physics/AABB.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#version 330 core
out vec4 FragColor;

uniform vec3 aabbColor = vec3(0,0.8,0);

void main() {
FragColor = vec4(aabbColor, 1.0);
}
10 changes: 10 additions & 0 deletions AimGL/resources/Shaders/Graphics/Physics/AABB.vs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#version 330 core
layout (location = 0) in vec3 aPos;

uniform mat4 model = mat4(1.0);
uniform mat4 view;
uniform mat4 projection;

void main() {
gl_Position = projection * view * model * vec4(aPos, 1.0);
}
2 changes: 1 addition & 1 deletion AimGL/resources/Shaders/Graphics/Physics/Ray.fs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#version 330 core
out vec4 FragColor;

uniform vec3 rayColor = vec3(0,1,0);
uniform vec3 rayColor = vec3(0,0.8,0);

void main() {
FragColor = vec4(rayColor, 1.0);
Expand Down
3 changes: 3 additions & 0 deletions AimGL/src/CMakeLists_Sources.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ set(PROJECT_SOURCES
World/Camera.cpp
World/InfiniteGridFloor.cpp
World/Scene/GameObjects/Rifle.cpp
World/Physics/Drawable/AABB.cpp
World/Physics/Drawable/Ray.cpp
World/Physics/Drawable/DrawableCollider.cpp
World/Physics/Collider.cpp
World/Physics/ColliderRegister.cpp
World/Physics/RayCollider.cpp
Expand Down
54 changes: 54 additions & 0 deletions AimGL/src/World/Physics/Drawable/AABB.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#include "AABB.h"
#include "pch.h"

#include "Renderer/Renderer.h"

void AABB::updateBuffers()
{
std::vector<float> vertices = {
// 8 corners of the AABB
mMin.x, mMin.y, mMin.z,// 0: Bottom-back-left
mMax.x, mMin.y, mMin.z,// 1: Bottom-back-right
mMin.x, mMax.y, mMin.z,// 2: Top-back-left
mMax.x, mMax.y, mMin.z,// 3: Top-back-right
mMin.x, mMin.y, mMax.z,// 4: Bottom-front-left
mMax.x, mMin.y, mMax.z,// 5: Bottom-front-right
mMin.x, mMax.y, mMax.z,// 6: Top-front-left
mMax.x, mMax.y, mMax.z,// 7: Top-front-right
};

std::vector<unsigned int> indices = {
// Each pair of indices represents one line segment
0, 1, 1, 5, 5, 4, 4, 0,// Bottom rectangle
2, 3, 3, 7, 7, 6, 6, 2,// Top rectangle
0, 2, 1, 3, 4, 6, 5, 7 // Connecting edges
};

mVBO.setBuffer(vertices);
mEBO.setBuffer(indices);
mVAO.setBuffer(mVBO, mBufferLayout);
}

AABB::AABB(ColliderRegister& colliderRegister, const glm::vec3& min, const glm::vec3& max)
: DrawableCollider(colliderRegister, min, max)
, mMin(mCollider.min)
, mMax(mCollider.max)
, mShader{{ShaderType::VertexShader, "resources/Shaders/Graphics/Physics/AABB.vs"},
{ShaderType::FragmentShader, "resources/Shaders/Graphics/Physics/AABB.fs"}}
{
mBufferLayout.push<float>(3);
updateBuffers();
}

void AABB::draw(const Renderer& target, const Camera& camera) const
{
target.draw3D(mVAO, mEBO, mShader, camera, Renderer::DrawMode::Lines);
}

void AABB::setPosition(const glm::vec3& position)
{
auto diff = mMax - mMin;
mMin = position;
mMax = mMin + diff;
updateBuffers();
}
66 changes: 66 additions & 0 deletions AimGL/src/World/Physics/Drawable/AABB.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#pragma once
#include "Renderer/Core/Buffers/BufferLayout.h"
#include "Renderer/Core/Buffers/IndexBuffer.h"
#include "Renderer/Core/Buffers/VertexBuffer.h"
#include "Renderer/Core/Shader.h"
#include "Renderer/Core/VertexArray.h"
#include "World/Physics/Drawable/DrawableCollider.h"
#include "World/Physics/RectangleCollider.h"

class Camera;
class Renderer;
class ColliderRegister;

/**
* \brief Axis-Aligned Bounding Box (AABB) with drawable and collision detection capabilities.
*/
class AABB : public DrawableCollider<RectangleCollider>
{
public:
/**
* \brief Constructs an Axis-Aligned Bounding Box (AABB) collider.
* \param colliderRegister Reference to the collision register for tracking this collider.
* \param min The minimum corner point of the AABB in 3D space.
* \param max The maximum corner point of the AABB in 3D space.
*/
AABB(ColliderRegister& colliderRegister, const glm::vec3& min, const glm::vec3& max);
AABB(AABB&&) noexcept = default;

/**
* \brief Draws a AABB for a given target
* \param target The target to which the AABB is drawn
* \param camera A camera in 3D space that looks at this object
*/
void draw(const Renderer& target, const Camera& camera) const;

/**
* Updates the AABB logic dependent, or independent of time, every rendered frame.
* \param deltaTime the time that has passed since the game was last updated.
*/
void update(const float& deltaTime);

/**
* \brief Sets the new AABB position
* \param position new position
*/
void setPosition(const glm::vec3& position);

private:
/**
* \brief Updates buffers (e.g., the position of vertices)
*
* TODO: The current update is rather pointless.
* It is better to pass transformations to the shader
*/
void updateBuffers();

private:
glm::vec3& mMin;
glm::vec3& mMax;

VertexArray mVAO;
VertexBuffer mVBO;
IndexBuffer mEBO;
BufferLayout mBufferLayout;
Shader mShader;
};
2 changes: 2 additions & 0 deletions AimGL/src/World/Physics/Drawable/DrawableCollider.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#include "DrawableCollider.h"
#include "pch.h"
70 changes: 70 additions & 0 deletions AimGL/src/World/Physics/Drawable/DrawableCollider.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#pragma once
#include "World/Physics/Collider.h"
#include "World/Physics/ColliderTag.h"


/**
* \brief A template class for colliders that are both drawable and functional in collision
* detection. \tparam ColliderType The type of collider this class is templating (e.g.,
* SphereCollider, RectangleCollider).
*/
template<typename ColliderType>
class DrawableCollider
{
public:
virtual ~DrawableCollider() = default;

/**
* \brief Constructor that initializes the collider with provided parameters.
* \tparam Args The types of arguments to forward to the ColliderType's constructor.
* \param params Arguments to forward to the ColliderType's constructor.
*/
template<typename... Args>
explicit DrawableCollider(Args&&... params);

/**
* \brief Sets a callback function to be executed when a collision occurs.
* \param callbackFunction The function to be called upon collision detection.
*/
void callback(std::function<void(const Collider&)> callbackFunction);

/**
* \brief Retrieves the tag of the collider.
* \return The tag that identifies the type of the collider.
*/
[[nodiscard]] ColliderTag colliderTag() const;

/**
* \brief Sets the tag identifying the type of the collider.
* \param colliderTag The tag to assign to the collider.
*/
void colliderTag(ColliderTag colliderTag);

protected:
ColliderType mCollider;
};

template<typename ColliderType>
template<typename... Args>
DrawableCollider<ColliderType>::DrawableCollider(Args&&... params)
: mCollider(std::forward<Args>(params)...)
{
}

template<typename ColliderType>
void DrawableCollider<ColliderType>::callback(std::function<void(const Collider&)> callbackFunction)
{
mCollider.callback(callbackFunction);
}

template<typename ColliderType>
ColliderTag DrawableCollider<ColliderType>::colliderTag() const
{
return mCollider.colliderTag();
}

template<typename ColliderType>
void DrawableCollider<ColliderType>::colliderTag(ColliderTag colliderTag)
{
mCollider.colliderTag(colliderTag);
}
29 changes: 29 additions & 0 deletions AimGL/src/World/Physics/Drawable/Ray.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#include "Ray.h"
#include "pch.h"

#include "Renderer/Renderer.h"

Ray::Ray(ColliderRegister& colliderRegister, const glm::vec3& origin, const glm::vec3& direction,
float length)
: DrawableCollider(colliderRegister, origin, direction, length)
, mOrigin(mCollider.origin)
, mDirection(mCollider.direction)
, mLength(mCollider.length)
, mShader{{ShaderType::VertexShader, "resources/Shaders/Graphics/Physics/Ray.vs"},
{ShaderType::FragmentShader, "resources/Shaders/Graphics/Physics/Ray.fs"}}
{
glm::vec3 endPoint = mOrigin + mDirection * mLength;

std::vector<float> vertices = {mOrigin.x, mOrigin.y, mOrigin.z,
endPoint.x, endPoint.y, endPoint.z};
mBufferLayout.push<float>(3);

mVBO.setBuffer(vertices);
mVAO.setBuffer(mVBO, mBufferLayout);
}

void Ray::draw(const Renderer& target, const Camera& camera) const
{
constexpr auto numberOfVertices = 6;
target.draw3D(mVAO, numberOfVertices, mShader, camera, Renderer::DrawMode::Lines);
}
51 changes: 51 additions & 0 deletions AimGL/src/World/Physics/Drawable/Ray.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#pragma once
#include "Renderer/Core/Buffers/BufferLayout.h"
#include "Renderer/Core/Buffers/VertexBuffer.h"
#include "Renderer/Core/Shader.h"
#include "Renderer/Core/VertexArray.h"
#include "World/Physics/Drawable/DrawableCollider.h"
#include "World/Physics/RayCollider.h"

class Camera;
class Renderer;
class ColliderRegister;

/**
* \brief Represents a ray in 3D space, defined by an origin point, direction vector, and length.
*/
class Ray : public DrawableCollider<RayCollider>
{
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.
*/
Ray(ColliderRegister& colliderRegister, const glm::vec3& origin, const glm::vec3& direction,
float length = 100);
Ray(Ray&&) noexcept = default;

/**
* \brief Draws a Ray for a given target
* \param target The target to which the model is drawn
* \param camera A camera in 3D space that looks at this object
*/
void draw(const Renderer& target, const Camera& camera) const;

/**
* Updates the Ray logic dependent, or independent of time, every rendered frame.
* \param deltaTime the time that has passed since the game was last updated.
*/
void update(const float& deltaTime);

private:
glm::vec3& mOrigin;
glm::vec3& mDirection;
float& mLength;
VertexArray mVAO;
VertexBuffer mVBO;
BufferLayout mBufferLayout;
Shader mShader;
};

0 comments on commit 2e215cb

Please sign in to comment.