Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 51 additions & 12 deletions Engine/include/BasicComponents/Physics2D.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <glm/vec3.hpp>

#include "Interface/IComponent.hpp"
#include "CollisionMode.hpp"
#ifdef _DEBUG
#include "BasicComponents/DynamicSprite.hpp"
#endif
Expand Down Expand Up @@ -45,7 +46,6 @@ class Physics2D : public IComponent

void Init() override ;
void Update(float dt) override;
void UpdateForParticle(float dt, glm::vec3& pos);
void End() override {};

void SetVelocity(glm::vec2 v) { velocity = v; }
Expand All @@ -63,42 +63,66 @@ class Physics2D : public IComponent
void AddForceX(float amount) { force.x = amount; }
void AddForceY(float amount) { force.y = amount; }

glm::vec2 GetAngularVelocity() const { return angularVelocity; }
float GetMomentOfInertia() const { return momentOfInertia; }
float GetInverseInertia() const { return inverseInertia; }

void SetAngularVelocity(glm::vec2 v) { angularVelocity = v; }
void AddTorque(glm::vec2 t) { torque += t; }
void SetMomentOfInertia(float i);

void SetFriction(float f) { friction = f; }
void SetGravity(float g, bool isGravityOn_ = true) { gravity = g; isGravityOn = isGravityOn_; }
void SetIsGravityOn(bool isGravityOn_) {isGravityOn = isGravityOn_; }
void SetGravity(float g, bool isGravityOnParam = true) { gravity = g; isGravityOn = isGravityOnParam; }
void SetIsGravityOn(bool isGravityOnParam) {isGravityOn = isGravityOnParam; }
void SetMass(float amount) { mass = amount; }
void SetRestitution(float amount) { restitution = amount; }
void SetBodyType(BodyType type) { bodyType = type; };
void SetIsGhostCollision(bool state) { isGhostCollision = state; }

// Getters
BodyType GetBodyType() { return bodyType; };
CollideType GetCollideType() { return collideType; };
float GetCircleCollideRadius() { return circle.radius; }
std::vector<glm::vec2> GetCollidePolygon() { return collidePolygon; }
float GetRestitution() { return restitution; }
bool GetIsGravityOn() const { return isGravityOn; }
bool GetIsGhostCollision() { return isGhostCollision; }
bool GetEnableRotationalPhysics() const { return enableRotationalPhysics; }

void SetEnableRotationalPhysics(bool v) { enableRotationalPhysics = v; }

float GetGravity() const { return gravity; }
float GetFriction() const { return friction; }
float GetMass() const { return mass; }
glm::vec2 GetMinVelocity() const { return velocityMin; }
glm::vec2 GetMaxVelocity() const { return velocityMax; }


bool CheckCollision(Object* obj);
bool CollisionPP(Object* obj, Object* obj2);
bool CollisionCC(Object* obj, Object* obj2);
bool CollisionPC(Object* poly, Object* cir);
bool CollisionPP(Object* obj, Object* obj2, CollisionMode mode = static_cast<CollisionMode>(0));
bool CollisionCC(Object* obj, Object* obj2, CollisionMode mode = static_cast<CollisionMode>(0));
bool CollisionPC(Object* poly, Object* cir, CollisionMode mode = static_cast<CollisionMode>(0));
bool CollisionPPWithoutPhysics(Object* obj, Object* obj2);

void AddCollideCircle(float r);
void AddCollidePolygon(glm::vec2 position);
void AddCollidePolygonAABB(glm::vec2 min, glm::vec2 max);
void AddCollidePolygonAABB(glm::vec2 size);
private:
glm::vec2 FindSATCenter(const std::vector<glm::vec2>& points_);
// Mathematical helper methods for collision detection
glm::vec2 FindSATCenter(const std::vector<glm::vec2>& points);
glm::vec2 FindClosestPointOnSegment(const glm::vec2& circleCenter, std::vector<glm::vec2>& vertices);
float calculatePolygonRadius(const std::vector<glm::vec2>& vertices);

float DegreesToRadians(float degrees);
glm::vec2 RotatePoint(const glm::vec2 point, const glm::vec2 size, float angle);
bool IsSeparatingAxis(const glm::vec2 axis, const std::vector<glm::vec2> points1, const std::vector<glm::vec2> points2, float* axisDepth, float* min1_, float* max1_, float* min2_, float* max2_);
bool IsSeparatingAxis(const glm::vec2 axis, const std::vector<glm::vec2> pointsPoly, const glm::vec2 pointCir, const float radius, float* axisDepth, float* min1_, float* max1_, float* min2_, float* max2_);

void CalculateLinearVelocity(Physics2D& body, Physics2D& body2, glm::vec2 normal, float* axisDepth);
// SAT (Separating Axis Theorem) helper functions
bool IsSeparatingAxis(const glm::vec2 axis, const std::vector<glm::vec2> points1, const std::vector<glm::vec2> points2, float* axisDepth, float* min1, float* max1, float* min2, float* max2);
bool IsSeparatingAxis(const glm::vec2 axis, const std::vector<glm::vec2> pointsPoly, const glm::vec2 pointCir, const float radius, float* axisDepth, float* min1, float* max1, float* min2, float* max2);

// Calculates and applies impulses due to collision
void CalculateLinearVelocity(Physics2D& body, Physics2D& body2, glm::vec2 normal, float* axisDepth, glm::vec2 contactPoint);

float Length(glm::vec2 a)
{
Expand All @@ -108,10 +132,20 @@ class Physics2D : public IComponent
{
return static_cast<float>(sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y)));
}

float LengthSquared(glm::vec2 a)
{
return (a.x * a.x) + (a.y * a.y);
}
float DistanceSquared(glm::vec2 a, glm::vec2 b)
{
return ((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}

Circle circle;
std::vector<glm::vec2> collidePolygon;

// Physical properties of the 2D body
glm::vec2 velocity = { 0.0f, 0.0f };
glm::vec2 velocityMin = { 0.f, 0.f };
glm::vec2 velocityMax = { 4.f, 4.f };
Expand All @@ -121,13 +155,18 @@ class Physics2D : public IComponent
float friction = 0.9f;
float gravity = 9.8f;
float mass = 1.f;
float restitution = 0.f;
//float rotateVelocity = 0.f;
float restitution = 0.f; // Bounciness factor

glm::vec2 angularVelocity = { 0.f, 0.f };
glm::vec2 torque = { 0.f, 0.f };
float momentOfInertia = 1.0f;
float inverseInertia = 1.0f;

CollideType collideType = CollideType::NONE;
BodyType bodyType = BodyType::RIGID;
bool isGhostCollision = false;
bool isGravityOn = false;
bool enableRotationalPhysics = false;
#ifdef _DEBUG
void AddPoint(glm::vec2 pos);
std::vector<Point> points;
Expand Down
80 changes: 58 additions & 22 deletions Engine/include/BasicComponents/Physics3D.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ struct CollisionResult
};



enum class BodyType3D
{
RIGID = 0,
Expand All @@ -45,16 +44,17 @@ struct Sphere
float radius = 0;
};

#include "CollisionMode.hpp"

class Physics3D : public IComponent
{
public:
Physics3D() : IComponent(ComponentTypes::PHYSICS3D) {/* Init(); */};
Physics3D() : IComponent(ComponentTypes::PHYSICS3D) { Init(); };
~Physics3D() override;

void Init() override ;
void Update(float dt) override;
void UpdatePhysics(float dt);
void UpdateForParticle(float dt, glm::vec3& pos);
void End() override {};

void SetVelocity(glm::vec3 v) { velocity = v; }
Expand All @@ -66,7 +66,15 @@ class Physics3D : public IComponent
void SetMinVelocity(glm::vec3 v) { velocityMin = v; }
void SetMaxVelocity(glm::vec3 v) { velocityMax = v; }

glm::vec3 GetVelocity() const { return velocity; }
glm::vec3 GetVelocity() const { return velocity; }
glm::vec3 GetAngularVelocity() const { return angularVelocity; }
float GetMomentOfInertia() const { return momentOfInertia; }
float GetInverseInertia() const { return inverseInertia; }

void SetAngularVelocity(glm::vec3 v) { angularVelocity = v; }
void AddTorque(glm::vec3 t) { torque += t; }
void SetMomentOfInertia(float i);

glm::vec3 GetMinVelocity() const { return velocityMin; }
glm::vec3 GetMaxVelocity() const { return velocityMax; }
float GetGravity() const { return gravity; }
Expand All @@ -77,16 +85,26 @@ class Physics3D : public IComponent
glm::vec3 GetPosition() const { return GetOwner()->GetPosition(); }
float GetRestitution() const { return restitution; }

void SetAcceleration(glm::vec3 v) { acceleration = v; };
void AddForce(glm::vec3 v) { force = v; }
void AddForceX(float amount) { force.x = amount; }
void AddForceY(float amount) { force.y = amount; }
void AddForceZ(float amount) { force.z = amount; }
void Awake();
void SetAcceleration(glm::vec3 v);
void AddForce(glm::vec3 v);
void AddForceX(float amount);
void AddForceY(float amount);
void AddForceZ(float amount);
void Teleport(glm::vec3 newPosition);

void SetFriction(float f) { friction = f; }
void SetGravity(float g, bool isGravityOn_ = true) { gravity = g; isGravityOn = isGravityOn_; }
void SetIsGravityOn(bool state) { isGravityOn = state; }
void SetGravity(float g, bool isGravityOnParam = true)
{
gravity = g;
isGravityOn = isGravityOnParam;
if (isGravityOnParam) Awake();
}
void SetIsGravityOn(bool state)
{
isGravityOn = state;
if (state) Awake();
}
void SetMass(float m);
void SetRestitution(float amount) { restitution = amount; }

Expand All @@ -101,21 +119,30 @@ class Physics3D : public IComponent
void SetIsGhostCollision(bool state) { isGhostCollision = state; }
void SetBodyType(BodyType3D type) { bodyType = type; };
void SetCollisionDetectionMode(CollisionDetectionMode mode) { collisionMode = mode; }
bool GetEnableRotationalPhysics() const { return enableRotationalPhysics; }
void SetEnableRotationalPhysics(bool v);

//2d->3d
std::vector<glm::vec3> GetCollidePolyhedron() { return collidePolyhedron; }
float GetSphereRadius() const { return sphere.radius; }

bool CheckCollision(Object* obj);
bool CollisionPP(Object* obj, Object* obj2);
bool CollisionSS(Object* obj, Object* obj2);
bool CollisionPS(Object* poly, Object* sph);
bool CollisionPP(Object* obj, Object* obj2, CollisionMode mode = static_cast<CollisionMode>(0));
bool CollisionSS(Object* obj, Object* obj2, CollisionMode mode = static_cast<CollisionMode>(0));
bool CollisionPS(Object* poly, Object* sph, CollisionMode mode = static_cast<CollisionMode>(0));

void AddCollidePolyhedron(glm::vec3 position);
void AddCollidePolyhedronAABB(glm::vec3 min, glm::vec3 max);
void AddCollidePolyhedronAABB(glm::vec3 size);
void AddCollideSphere(float r);
//2d->3d

// Made public so PhysicsManager can drive the CCD loop directly.
CollisionResult FindClosestCollision(float dt);
void CalculateLinearVelocity(Physics3D& body, Physics3D& body2, glm::vec3 normal, float* axisDepth, glm::vec3 contactPoint, float impulseScale = 1.0f);

private:
// Linear Physical Properties
glm::vec3 velocity = { 0.0f, 0.0f, 0.0f };
glm::vec3 velocityMin = { 0.f, 0.f, 0.0f };
glm::vec3 velocityMax = { 4.f, 4.f, 4.f };
Expand All @@ -125,26 +152,36 @@ class Physics3D : public IComponent
float friction = 0.9f;
float gravity = 9.8f;
float mass = 1.f;
float restitution = 0.f;
glm::quat orientation = glm::quat{ 1.0f, 0.0f, 0.0f, 0.0f };
float restitution = 0.f; // Bounciness factor
glm::quat orientation = glm::quat(1.0f, 0.0f, 0.0f, 0.0f);

// Physics States
bool isGhostCollision = false;
bool isGravityOn = false;
bool enableRotationalPhysics = false;
bool isSleeping = false;
float sleepTimer = 0.0f;
float angularDamping = 0.5f;

glm::vec3 angularVelocity = { 0.f, 0.f, 0.f };
glm::vec3 torque = { 0.f, 0.f, 0.f };
float momentOfInertia = 1.0f;
float inverseInertia = 1.0f;

ColliderType3D colliderType = ColliderType3D::BOX;
BodyType3D bodyType = BodyType3D::RIGID;
CollisionDetectionMode collisionMode = CollisionDetectionMode::DISCRETE;

//2d->3d
glm::vec3 FindSATCenter(const std::vector<glm::vec3>& points_);
// Discrete Collision Helpers (SAT)
glm::vec3 FindSATCenter(const std::vector<glm::vec3>& points);
glm::vec3 RotatePoint(const glm::vec3& point, const glm::vec3& position, const glm::quat& rotation);
bool IsSeparatingAxis(const glm::vec3 axis, const std::vector<glm::vec3> points1, const std::vector<glm::vec3> points2, float* axisDepth, float* min1_, float* max1_, float* min2_, float* max2_);
void CalculateLinearVelocity(Physics3D& body, Physics3D& body2, glm::vec3 normal, float* axisDepth);
bool IsSeparatingAxis(const glm::vec3 axis, const std::vector<glm::vec3> points1, const std::vector<glm::vec3> points2, float* axisDepth, float* min1, float* max1, float* min2, float* max2);

glm::vec3 FindClosestPointOnSegment(const glm::vec3& sphereCenter, std::vector<glm::vec3>& vertices);
bool IsSeparatingAxis(const glm::vec3 axis, const std::vector<glm::vec3> pointsPoly, const glm::vec3 pointSphere, const float radius, float* axisDepth, float* min1_, float* max1_, float* min2_, float* max2_);
bool IsSeparatingAxis(const glm::vec3 axis, const std::vector<glm::vec3> pointsPoly, const glm::vec3 pointSphere, const float radius, float* axisDepth, float* min1, float* max1, float* min2, float* max2);

//CollisionDetectionMode : Continuous
// Continuous Collision Helpers (CCD)
void ProjectPolygon(const std::vector<glm::vec3>& vertices, const glm::vec3& axis, float& min, float& max);
bool StaticSATIntersection(Physics3D* body1, Physics3D* body2,
const std::vector<glm::vec3>& rotatedPoly1, const std::vector<glm::vec3>& rotatedPoly2,
Expand All @@ -153,7 +190,6 @@ class Physics3D : public IComponent
bool SweptSATOBB(Physics3D* body1, Physics3D* body2, float dt, CollisionResult& outResult);
bool SweptSpheres(Physics3D* body1, Physics3D* body2, float dt, CollisionResult& outResult);
bool SweptSphereVsOBB(Physics3D* boxBody, float dt, CollisionResult& outResult);
CollisionResult FindClosestCollision(float dt);
//CollisionDetectionMode : Continuous

std::vector<glm::vec3> collidePolyhedron;
Expand Down
1 change: 1 addition & 0 deletions Engine/include/Camera.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ class Camera
float GetCameraSensitivity() { return cameraSensitivity; }

void SetCameraType(CameraType type) { cameraType = type; }
CameraType GetCameraType() const { return cameraType; }
void SetNear(float amount) noexcept { nearClip = amount; }
void SetFar(float amount) noexcept { farClip = amount; }
void SetPitch(float amount) noexcept { pitch = amount; }
Expand Down
1 change: 1 addition & 0 deletions Engine/include/CameraManager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class CameraManager
void Init(glm::vec2 viewSize, CameraType type = CameraType::TwoDimension, float zoom = 45.f, float angle = 0.f);
void Update();
void Reset();
CameraType GetCameraType() const { return camera.GetCameraType(); }

// 2D, 3D
void SetZoom(float zoom) noexcept { camera.SetZoom(zoom); }
Expand Down
8 changes: 8 additions & 0 deletions Engine/include/CollisionMode.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#pragma once

enum class CollisionMode
{
COLLIDE,
DETECT,
IGNORED
};
3 changes: 3 additions & 0 deletions Engine/include/Engine.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "ThreadManager.hpp"
#include "Logger.hpp"
#include "Particle/ParticleManager.hpp"
#include "PhysicsManager.hpp"

class Engine
{
Expand All @@ -31,6 +32,7 @@ class Engine
static SoundManager& GetSoundManager() { return Instance().soundManager; }
static SpriteManager& GetSpriteManager() { return *Instance().spriteManager; }
static ParticleManager& GetParticleManager() { return Instance().particleManager; }
static PhysicsManager& GetPhysicsManager() { return Instance().physicsManager; }
static Timer& GetTimer() { return Instance().timer; }
static Logger& GetLogger() { return *Instance().logger; }

Expand Down Expand Up @@ -58,6 +60,7 @@ class Engine
SoundManager soundManager;
SpriteManager* spriteManager;
ParticleManager particleManager;
PhysicsManager physicsManager;
ThreadManager threadManager;
Logger* logger;
};
1 change: 0 additions & 1 deletion Engine/include/GameStateManager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ class GameStateManager
private:
const char* GameLevelTypeEnumToChar(GameLevel type);
void LevelInit();
void CollideObjects();

GameLevel currentLevel = GameLevel::NONE;
GameLevel levelSelected = GameLevel::NONE;
Expand Down
3 changes: 3 additions & 0 deletions Engine/include/ObjectManager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

class DynamicSprite;
class Physics3D;
class Physics2D;
class Light;

class SkeletalAnimator;
Expand Down Expand Up @@ -95,7 +96,9 @@ class ObjectManager
void ProcessFunctionQueue();
private:
void Physics3DControllerForImGui(Physics3D* phy);
void Physics2DControllerForImGui(Physics2D* phy);
void RenderPhysics3DDebug(Physics3D* phy);
void RenderPhysics2DDebug(Physics2D* phy);
void SpriteControllerForImGui(DynamicSprite* sprite);
void LightControllerForImGui(Light* light);

Expand Down
Loading
Loading