#include "RigidbodyComponent.h" #include "ColliderComponent.h" #include "GameObject.h" #include dae::RigidbodyComponent::~RigidbodyComponent() { } void dae::RigidbodyComponent::Initialize() { m_pColliderComponent = GetGameObject()->GetComponent(); } bool dae::RigidbodyComponent::Move(float x, float y, const std::vector& pColliders) { m_DidCollide = false; auto& colliderData = m_pColliderComponent->GetColliderData(); auto collisionRect = m_pColliderComponent->GetCollisionRect(); auto pos = GetGameObject()->GetWorldPosition(); float collisionX{}; float collisionY{}; if (x != 0) { GetGameObject()->SetPosition(pos.x + x, pos.y); if (IsCollidingWith(pColliders, collisionX, collisionY)) { m_DidCollide = true; if (x > 0) GetGameObject()->SetPosition(collisionX - colliderData.offsetX - colliderData.width, pos.y); else if (x < 0) GetGameObject()->SetPosition(collisionX - colliderData.offsetX, pos.y); } } if (y != 0) { pos = GetGameObject()->GetWorldPosition(); GetGameObject()->SetPosition(pos.x, pos.y + y); if (IsCollidingWith(pColliders, collisionX, collisionY)) { m_DidCollide = true; if (y > 0) { GetGameObject()->SetPosition(pos.x, collisionY - colliderData.offsetY - colliderData.height); float minY = std::min({ collisionRect.p0y, collisionRect.p1y, collisionRect.p2y, collisionRect.p3y }); return (minY <= collisionY); } else if (y < 0) GetGameObject()->SetPosition(pos.x, collisionY - colliderData.offsetY); } } float rayCastDistance{ 4.f }; pos = GetGameObject()->GetWorldPosition(); GetGameObject()->SetPosition(pos.x, pos.y + rayCastDistance); if (IsCollidingWith(pColliders, collisionX, collisionY)) { float minY = std::min({ collisionRect.p2y, collisionRect.p2y, collisionRect.p2y, collisionRect.p2y }); float minY2 = std::min({ collisionRect.p3y, collisionRect.p3y, collisionRect.p3y, collisionRect.p3y }); GetGameObject()->SetPosition(pos.x, pos.y); return (minY <= collisionY || minY2 <= collisionY); } else { GetGameObject()->SetPosition(pos.x, pos.y); return false; } } bool dae::RigidbodyComponent::IsCollidingWith(const std::vector& pColliders, float& collisionX, float& collisionY, bool includeEdges) { auto collisionRect = m_pColliderComponent->GetCollisionRect(); m_LastCollidedGo = nullptr; bool didCollide{ false }; for (auto pCollider : pColliders) { if (!pCollider->GetGameObject()->IsActive()) continue; m_LastCollidedGo = pCollider->GetGameObject(); auto otherCollisionRect = pCollider->GetCollisionRect(); didCollide = IsPointInRect(otherCollisionRect.p0x, otherCollisionRect.p0y, collisionRect, includeEdges); collisionX = otherCollisionRect.p0x; collisionY = otherCollisionRect.p0y; if (didCollide) break; didCollide = IsPointInRect(otherCollisionRect.p1x, otherCollisionRect.p1y, collisionRect, includeEdges); collisionX = otherCollisionRect.p1x; collisionY = otherCollisionRect.p1y; if (didCollide) break; didCollide = IsPointInRect(otherCollisionRect.p2x, otherCollisionRect.p2y, collisionRect, includeEdges); collisionX = otherCollisionRect.p2x; collisionY = otherCollisionRect.p2y; if (didCollide) break; didCollide = IsPointInRect(otherCollisionRect.p3x, otherCollisionRect.p3y, collisionRect, includeEdges); collisionX = otherCollisionRect.p3x; collisionY = otherCollisionRect.p3y; if (didCollide) break; } return didCollide; } void dae::RigidbodyComponent::Update(float) { } void dae::RigidbodyComponent::FixedUpdate(float) { } bool dae::RigidbodyComponent::IsPointInRect(float x, float y, const CollisionRect& collisionRect, bool includeEdges) { float minX = std::min({ collisionRect.p0x, collisionRect.p1x, collisionRect.p2x, collisionRect.p3x }); float maxX = std::max({ collisionRect.p0x, collisionRect.p1x, collisionRect.p2x, collisionRect.p3x }); float minY = std::min({ collisionRect.p0y, collisionRect.p1y, collisionRect.p2y, collisionRect.p3y }); float maxY = std::max({ collisionRect.p0y, collisionRect.p1y, collisionRect.p2y, collisionRect.p3y }); if (!includeEdges) return (x > minX && x < maxX && y > minY && y < maxY); else return (x >= minX && x <= maxX && y >= minY && y <= maxY); }