Skip to content

Commit

Permalink
Add collisions
Browse files Browse the repository at this point in the history
  • Loading branch information
Notiooo committed Dec 7, 2023
1 parent 49134b7 commit 7eaefb5
Show file tree
Hide file tree
Showing 30 changed files with 491 additions and 19 deletions.
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
9 changes: 8 additions & 1 deletion AimGL/src/CMakeLists_Sources.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@ set(PROJECT_SOURCES
World/Camera.cpp
World/InfiniteGridFloor.cpp
World/Scene/GameObjects/Rifle.cpp
World/Physics/Ray.cpp
World/Physics/Drawable/AABB.cpp
World/Physics/Drawable/Ray.cpp
World/Physics/Collider.cpp
World/Physics/CollisionRegister.cpp
World/Physics/RayCollider.cpp
World/Physics/RectangleCollider.cpp
World/Physics/SphereCollider.cpp
World/Physics/Collisions.cpp
Utils/Mouse.cpp
)
2 changes: 1 addition & 1 deletion AimGL/src/Game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ Game::Game()
mAppStack.saveState<GameState>(State_ID::GameState, *mGameWindow);

// Initial state of the statestack is TitleState
mAppStack.push(State_ID::LogoState);
mAppStack.push(State_ID::GameState);
}

void Game::run()
Expand Down
4 changes: 2 additions & 2 deletions AimGL/src/Player/Player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
#include "Utils/Lerp.h"
#include "pch.h"

Player::Player(WindowToRender& window)
Player::Player(WindowToRender& window, CollisionRegister& collisionRegister)
: mCamera(window)
, mCrosshairTexture("resources/Textures/crosshair.png")
, mCrosshair(mCrosshairTexture)
, mRifle(mCamera)
, mRifle(mCamera, collisionRegister)
{
mCrosshair.setPosition({window.getSize().x / 2.f, window.getSize().y / 2.f},
Sprite2D::Origin::Center);
Expand Down
3 changes: 2 additions & 1 deletion AimGL/src/Player/Player.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ class Player
/**
* \brief Player class constructor
* \param window The window into which the player's eye view is rendered
* \param collisionRegister TODO: THIS
*/
explicit Player(WindowToRender& window);
Player(WindowToRender& window, CollisionRegister& collisionRegister);

static constexpr auto PLAYER_HEGIHT = 0.8f;
static constexpr auto PLAYER_MAX_HORIZONTAL_SPEED = 5.f;
Expand Down
4 changes: 3 additions & 1 deletion AimGL/src/States/CustomStates/GameState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
GameState::GameState(StateStack& stack, WindowToRender& window)
: State(stack)
, mWindow(window)
, mPlayer(window)
, mPlayer(window, mCollisionRegister)
, mRenderer(mWindow)
, mLogoTexture("resources/Textures/logo_background.png")
, mLogo(mLogoTexture)
Expand Down Expand Up @@ -39,12 +39,14 @@ void GameState::draw(sf::Window& target) const
mLogo.draw(mRenderer, mPlayer.camera());
mPhaseInLogoColor.draw(mRenderer);
mPlayer.draw(mRenderer);
mAABB.draw(mRenderer, mPlayer.camera());
}

bool GameState::fixedUpdate(const float& deltaTime)
{
MTR_SCOPE("GameState", "GameState::fixedUpdate");
mPlayer.fixedUpdate(deltaTime);
mCollisionRegister.updateAllCollisions();
return true;
}

Expand Down
4 changes: 4 additions & 0 deletions AimGL/src/States/CustomStates/GameState.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

#include <Player/Player.h>
#include <Renderer/Graphics/3D/Model.h>
#include <World/Physics/CollisionRegister.h>
#include <World/Physics/Drawable/AABB.h>

class StateStack;

Expand Down Expand Up @@ -53,6 +55,7 @@ class GameState : public State

private:
WindowToRender& mWindow;
CollisionRegister mCollisionRegister;
Player mPlayer;
Renderer mRenderer;
Texture mLogoTexture;
Expand All @@ -62,4 +65,5 @@ class GameState : public State
Rectangle2D mPhaseInLogoColor;
InfiniteGridFloor mInfiniteGridFloor;
Model mTree;
AABB mAABB{mCollisionRegister, {0, 0, 0}, {2, 2, 2}};
};
29 changes: 29 additions & 0 deletions AimGL/src/World/Physics/Collider.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#include "Collider.h"

#include "World/Physics/CollisionRegister.h"
#include "pch.h"
#include <utility>

Collider::Collider(CollisionRegister& collisionRegister)
: mCollisionRegister(collisionRegister)
{
mCollisionRegister.add(*this);
}

Collider::~Collider()
{
mCollisionRegister.remove(*this);
}

void Collider::executeCallBack(const Collider& other) const
{
if (mCallback)
{
mCallback(other);
}
}

void Collider::setCallBack(std::function<void(const Collider&)> callbackFunction)
{
mCallback = std::move(callbackFunction);
}
23 changes: 23 additions & 0 deletions AimGL/src/World/Physics/Collider.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#pragma once

class SphereCollider;
class RectangleCollider;
class RayCollider;
class CollisionRegister;

class Collider
{
public:
Collider(CollisionRegister& collisionRegister);
virtual ~Collider();
[[nodiscard]] virtual bool checkCollision(const Collider& other) const = 0;
[[nodiscard]] virtual bool checkCollisionWith(const SphereCollider& other) const = 0;
[[nodiscard]] virtual bool checkCollisionWith(const RectangleCollider& other) const = 0;
[[nodiscard]] virtual bool checkCollisionWith(const RayCollider& other) const = 0;
void executeCallBack(const Collider& other) const;
virtual void setCallBack(std::function<void(const Collider&)> callbackFunction);

private:
std::function<void(const Collider&)> mCallback;
CollisionRegister& mCollisionRegister;
};
8 changes: 8 additions & 0 deletions AimGL/src/World/Physics/ColliderTag.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#pragma once

enum class ColliderTag
{
None,
Solid,
GunShot,
};
28 changes: 28 additions & 0 deletions AimGL/src/World/Physics/CollisionRegister.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#include "CollisionRegister.h"
#include "Collider.h"
#include "pch.h"

void CollisionRegister::add(const Collider& collider)
{
mColliders.push_back(&collider);
}

void CollisionRegister::remove(const Collider& collider)
{
mColliders.erase(std::find(mColliders.begin(), mColliders.end(), &collider));
}

void CollisionRegister::updateAllCollisions()
{
for (size_t i = 0; i < mColliders.size(); ++i)
{
for (size_t j = i + 1; j < mColliders.size(); ++j)
{
if (mColliders[i]->checkCollision(*mColliders[j]))
{
mColliders[i]->executeCallBack(*mColliders[j]);
mColliders[j]->executeCallBack(*mColliders[i]);
}
}
}
}
14 changes: 14 additions & 0 deletions AimGL/src/World/Physics/CollisionRegister.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#pragma once

class Collider;

class CollisionRegister
{
public:
void add(const Collider& collider);
void remove(const Collider& collider);
void updateAllCollisions();

private:
std::vector<const Collider*> mColliders;
};
60 changes: 60 additions & 0 deletions AimGL/src/World/Physics/Collisions.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#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;// Set tMax to rayLength instead of infinity

for (int i = 0; i < 3; ++i)
{
if (std::abs(ray.direction[i]) < std::numeric_limits<float>::epsilon())
{
// Ray is parallel to slab. No hit if origin not within slab
if (ray.origin[i] < rectangle.min[i] || ray.origin[i] > rectangle.max[i])
{
return false;
}
}
else
{
// Compute intersection t value of ray with near and far plane of slab
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;
// Make t1 be intersection with near plane, t2 with far plane
if (t1 > t2)
{
std::swap(t1, t2);
}
// Compute the intersection of slab intersection intervals
tMin = std::max(tMin, t1);
tMax = std::min(tMax, t2);
// Exit with no collision as soon as slab intersection becomes empty
if (tMin > tMax)
{
return false;
}
}
}
// Ray intersects all 3 slabs. Return point (tMin is the first contact)
// Check if the intersection is within the ray's length
return tMin <= ray.length;
}
13 changes: 13 additions & 0 deletions AimGL/src/World/Physics/Collisions.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#pragma once


class SphereCollider;
class RectangleCollider;
class RayCollider;

bool checkSphereRectangleCollision(const SphereCollider& sphere,
const RectangleCollider& rectangle);

bool checkRayRectangleCollision(const RayCollider& ray, const RectangleCollider& rectangle);

bool checkRaySphereCollision(const RayCollider& ray, const SphereCollider& sphere);
42 changes: 42 additions & 0 deletions AimGL/src/World/Physics/Drawable/AABB.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#include "AABB.h"
#include "pch.h"

#include <Renderer/Renderer.h>

AABB::AABB(CollisionRegister& collisionRegister, const glm::vec3& min, const glm::vec3& max)
: mCollider(collisionRegister, 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"}}
{
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
};

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
};

mBufferLayout.push<float>(3);

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

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

#include <Renderer/Core/Buffers/IndexBuffer.h>
#include <Renderer/Core/Shader.h>
#include <World/Physics/RectangleCollider.h>

class Camera;
class Renderer;

/**
* \brief TODO: THIS
*/
class AABB
{
public:
AABB(CollisionRegister& collisionRegister, 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);

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

VertexArray mVAO;
VertexBuffer mVBO;
IndexBuffer mEBO;
BufferLayout mBufferLayout;
Shader mShader;
};
Loading

0 comments on commit 7eaefb5

Please sign in to comment.