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
8 changes: 4 additions & 4 deletions Engine/include/BasicComponents/DynamicSprite.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class Animation;
class DynamicSprite : public ISprite
{
public:
DynamicSprite() : ISprite() { Init(); spriteType = SpriteType::DYNAMIC; };
DynamicSprite() : ISprite() { spriteType = SpriteType::DYNAMIC; };
~DynamicSprite() override;

void Init() override;
Expand All @@ -27,11 +27,11 @@ class DynamicSprite : public ISprite
void UpdateProjection() override;

// Add Quad
void AddQuad(glm::vec4 color_);
void AddQuadWithTexture(std::string name_, glm::vec4 color_ = { 1.f,1.f,1.f,1.f }, bool isTexel_ = false);
void CreateQuad(glm::vec4 color_);
void CreateQuadWithTexture(std::string name_, glm::vec4 color_ = { 1.f,1.f,1.f,1.f }, bool isTexel_ = false);

// Animation
void LoadAnimation(const std::filesystem::path& spriteInfoFile, std::string name);
void LoadAnimationData(const std::filesystem::path& spriteInfoFile, std::string name);
glm::vec2 GetHotSpot(int index);
glm::vec2 GetFrameSize() const { return frameSize; };

Expand Down
2 changes: 1 addition & 1 deletion Engine/include/BasicComponents/Light.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class DynamicSprite;
class Light : public IComponent
{
public:
Light() : IComponent(ComponentTypes::LIGHT) { Init(); };
Light() : IComponent(ComponentTypes::LIGHT) {};
~Light() override;

void Init() override;
Expand Down
13 changes: 10 additions & 3 deletions Engine/include/BasicComponents/Physics2D.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <vector>
#include <glm/vec2.hpp>
#include <glm/vec3.hpp>
#include <unordered_map>

#include "Interface/IComponent.hpp"
#include "CollisionMode.hpp"
Expand Down Expand Up @@ -41,7 +42,7 @@ struct Circle
class Physics2D : public IComponent
{
public:
Physics2D() : IComponent(ComponentTypes::PHYSICS2D) { Init(); };
Physics2D() : IComponent(ComponentTypes::PHYSICS2D) {};
~Physics2D() override;

void Init() override ;
Expand Down Expand Up @@ -108,6 +109,9 @@ class Physics2D : public IComponent
void AddCollidePolygon(glm::vec2 position);
void AddCollidePolygonAABB(glm::vec2 min, glm::vec2 max);
void AddCollidePolygonAABB(glm::vec2 size);

// Remove the destroyed body from the cache to prevent dangling pointers
void RemoveFromCollisionCache(Physics2D* otherBody){ separatingAxisCache.erase(otherBody); }
private:
// Mathematical helper methods for collision detection
glm::vec2 FindSATCenter(const std::vector<glm::vec2>& points);
Expand All @@ -118,8 +122,8 @@ class Physics2D : public IComponent
glm::vec2 RotatePoint(const glm::vec2 point, const glm::vec2 size, float angle);

// 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);
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& pointCircle, 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);
Expand Down Expand Up @@ -167,6 +171,9 @@ class Physics2D : public IComponent
bool isGhostCollision = false;
bool isGravityOn = false;
bool enableRotationalPhysics = false;

// Cache for Temporal Coherence (Separating Axis Theorem)
std::unordered_map<Physics2D*, glm::vec2> separatingAxisCache;
#ifdef _DEBUG
void AddPoint(glm::vec2 pos);
std::vector<Point> points;
Expand Down
116 changes: 82 additions & 34 deletions Engine/include/BasicComponents/Physics3D.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#pragma warning(disable : 4201)
#include <glm/gtc/quaternion.hpp>
#pragma warning(default : 4201)
#include <unordered_map>

#include "Interface/IComponent.hpp"
#include "Object.hpp"
Expand All @@ -26,7 +27,6 @@ struct CollisionResult
glm::vec3 collisionNormal = { 0.f, 0.f, 0.f };
};


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

struct SupportPoint
{
glm::vec3 minkowskiDifference;
glm::vec3 pointOnA;
glm::vec3 pointOnB;
};

struct EpaFace
{
glm::vec3 normal;
float distance;
int vertexIndices[3];
};

struct GjkShape
{
ColliderType3D type;
const std::vector<glm::vec3>* vertices = nullptr;
glm::vec3 center = { 0.0f, 0.0f, 0.0f };
float radius = 0.0f;
glm::vec3 offset = { 0.0f, 0.0f, 0.0f };
};

#include "CollisionMode.hpp"

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

void Init() override ;
void Init() override;
void Update(float dt) override;
void UpdatePhysics(float dt);
void End() override {};
Expand Down Expand Up @@ -94,16 +117,16 @@ class Physics3D : public IComponent
void Teleport(glm::vec3 newPosition);

void SetFriction(float f) { friction = f; }
void SetGravity(float g, bool isGravityOnParam = true)
{
gravity = g;
isGravityOn = isGravityOnParam;
if (isGravityOnParam) Awake();
void SetGravity(float g, bool isGravityOnParam = true)
{
gravity = g;
isGravityOn = isGravityOnParam;
if (isGravityOnParam) Awake();
}
void SetIsGravityOn(bool state)
{
isGravityOn = state;
if (state) Awake();
void SetIsGravityOn(bool state)
{
isGravityOn = state;
if (state) Awake();
}
void SetMass(float m);
void SetRestitution(float amount) { restitution = amount; }
Expand All @@ -122,7 +145,7 @@ class Physics3D : public IComponent
bool GetEnableRotationalPhysics() const { return enableRotationalPhysics; }
void SetEnableRotationalPhysics(bool v);

//2d->3d
// Methods for handling collisions mapped from two-dimensional space to three-dimensional space
std::vector<glm::vec3> GetCollidePolyhedron() { return collidePolyhedron; }
float GetSphereRadius() const { return sphere.radius; }

Expand All @@ -135,12 +158,24 @@ class Physics3D : public IComponent
void AddCollidePolyhedronAABB(glm::vec3 min, glm::vec3 max);
void AddCollidePolyhedronAABB(glm::vec3 size);
void AddCollideSphere(float r);
//2d->3d
// End of methods for mapping two-dimensional space to three-dimensional space

// 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);

void RemoveFromCollisionCache(Physics3D* otherBody)
{
separatingAxisCache.erase(otherBody);
}


//======== Legacy: SAT ========//
//bool CollisionPPSAT(Object* obj, Object* obj2, CollisionMode mode = static_cast<CollisionMode>(0));
//bool CollisionSSSAT(Object* obj, Object* obj2, CollisionMode mode = static_cast<CollisionMode>(0));
//bool CollisionPSSAT(Object* poly, Object* sph, CollisionMode mode = static_cast<CollisionMode>(0));
//======== Legacy: SAT ========//

private:
// Linear Physical Properties
glm::vec3 velocity = { 0.0f, 0.0f, 0.0f };
Expand Down Expand Up @@ -168,33 +203,46 @@ class Physics3D : public IComponent
float momentOfInertia = 1.0f;
float inverseInertia = 1.0f;

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

//2d->3d
// 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);

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

// 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,
const glm::mat4& rotationMatrix1, const glm::mat4& rotationMatrix2,
glm::vec3& outNormal, float& outDepth);
bool SweptSATOBB(Physics3D* body1, Physics3D* body2, float dt, CollisionResult& outResult);
glm::vec3 ComputePolygonCenter(const std::vector<glm::vec3>& points);
// Continuous collision detection mode for preventing tunneling at high speeds
bool SweptSpheres(Physics3D* body1, Physics3D* body2, float dt, CollisionResult& outResult);
bool SweptSphereVsOBB(Physics3D* boxBody, float dt, CollisionResult& outResult);
//CollisionDetectionMode : Continuous

// Gilbert-Johnson-Keerthi distance algorithm and Expanding Polytope Algorithm for convex collision resolution
// universal support function that handles all shape types
glm::vec3 GetShapeSupportPoint(const GjkShape& shape, glm::vec3 searchDirection);
// updated gjk and epa signatures using GjkShape
SupportPoint GetSupport(const GjkShape& shapeA, const GjkShape& shapeB, glm::vec3 searchDirection);
bool CheckCollisionGJK(const GjkShape& shapeA, const GjkShape& shapeB, std::vector<SupportPoint>& outSimplex);
bool HandleSimplex(std::vector<SupportPoint>& currentSimplex, glm::vec3& currentDirection);
void CalculatePenetrationEPA(const GjkShape& shapeA, const GjkShape& shapeB, std::vector<SupportPoint>& currentSimplex, glm::vec3& outNormal, float& outDepth, glm::vec3& outContactPoint);
// Helper methods for Continuous Collision Detection to solve time of impact
bool SweptGJK(Physics3D* body1, Physics3D* body2, float dt, CollisionResult& outResult);

std::vector<glm::vec3> collidePolyhedron;
Sphere sphere;

//2d->3d
// Cache previous separating axes to exploit temporal coherence and accelerate the algorithm in subsequent frames
std::unordered_map<Physics3D*, glm::vec3> separatingAxisCache;

//======== Legacy: SAT ========//
//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);
//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);

//glm::vec3 FindClosestPointOnSegment(const glm::vec3& sphereCenter, std::vector<glm::vec3>& vertices);

//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,
// const glm::mat4& rotationMatrix1, const glm::mat4& rotationMatrix2,
// glm::vec3& outNormal, float& outDepth);
//bool SweptSATOBB(Physics3D* body1, Physics3D* body2, float dt, CollisionResult& outResult);
//bool SweptSphereVsOBB(Physics3D* boxBody, float dt, CollisionResult& outResult);
//======== Legacy: SAT ========//

//@TODO: Create Capsule collider type
};
5 changes: 4 additions & 1 deletion Engine/include/BasicComponents/SkeletalAnimator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,12 @@ class SkeletalAnimator : public IComponent
{
public:
SkeletalAnimator();
~SkeletalAnimator() override;

void Init() override;
void Update(float dt) override;
void Update(float dt) override; // Wrapper: calls UpdateBoneTransforms + QueueGPUBoneUpload
void UpdateBoneTransforms(float dt); // CPU only: time advance, bone transform calculation
void QueueGPUBoneUpload(); // Queues GPU buffer upload to main thread
void End() override;

// Animation Control
Expand Down
2 changes: 1 addition & 1 deletion Engine/include/BasicComponents/StaticSprite.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class StaticSprite : public ISprite
uint32_t primitiveIndexOffset;
};

StaticSprite() : ISprite() { Init(); spriteType = SpriteType::STATIC; };
StaticSprite() : ISprite() { spriteType = SpriteType::STATIC; };
~StaticSprite() override;

void Init() override;
Expand Down
Loading
Loading