From 65c01f9b8e8d1bd6d644ccb2ec26a89e7b3fb242 Mon Sep 17 00:00:00 2001 From: viktorljung Date: Tue, 6 Oct 2015 19:41:00 +0200 Subject: [PATCH] Improved collisions with multiple objects in the same frame --- include/Game/BallSystem.h | 8 +++-- src/game/Game/BallSystem.cpp | 53 +++++++++++++++++++++++++++--- src/game/Physics/PhysicsSystem.cpp | 2 +- 3 files changed, 55 insertions(+), 8 deletions(-) diff --git a/include/Game/BallSystem.h b/include/Game/BallSystem.h index 1d06e6b..d444cb3 100644 --- a/include/Game/BallSystem.h +++ b/include/Game/BallSystem.h @@ -40,8 +40,7 @@ public: ~BallSystem(); - EventRelay m_Contact; - bool Contact(const Events::Contact &event); + void RegisterComponents(ComponentFactory *cf) override; @@ -100,12 +99,17 @@ private: EntityID m_Ball; + std::unordered_map> m_Contacts; + void ResolveContacts(); + dd::EventRelay m_ELifeLost; dd::EventRelay m_EMultiBallLost; dd::EventRelay m_EResetBall; dd::EventRelay m_EMultiBall; dd::EventRelay m_EPause; + EventRelay m_Contact; + bool Contact(const Events::Contact &event); bool OnLifeLost(const dd::Events::LifeLost &event); bool OnMultiBallLost(const dd::Events::MultiBallLost &event); bool OnResetBall(const dd::Events::ResetBall &event); diff --git a/src/game/Game/BallSystem.cpp b/src/game/Game/BallSystem.cpp index 4026bfe..9c83217 100644 --- a/src/game/Game/BallSystem.cpp +++ b/src/game/Game/BallSystem.cpp @@ -25,12 +25,12 @@ void dd::Systems::BallSystem::Initialize() auto ent = m_World->CreateEntity(); std::shared_ptr transform = m_World->AddComponent(ent); transform->Position = glm::vec3(-0.f, 50.26f, -10.f); - transform->Scale = glm::vec3(0.5f, 0.5f, 0.5f); + transform->Scale = glm::vec3(0.2f, 0.2f, 0.2f); transform->Velocity = glm::vec3(0.f, 0.f, 0.f); auto model = m_World->AddComponent(ent); - model->ModelFile = "Models/Test/Ball/Ballopus.obj"; + model->ModelFile = "Models/Test/Ball/Sid.obj"; std::shared_ptr circleShape = m_World->AddComponent(ent); - circleShape->Radius = 0.5f; + circleShape->Radius = 0.2f; std::shared_ptr ball = m_World->AddComponent(ent); ball->Speed = 5.f; std::shared_ptr physics = m_World->AddComponent(ent); @@ -68,6 +68,7 @@ void dd::Systems::BallSystem::Update(double dt) Events::GameOver e; EventBroker->Publish(e); } + ResolveContacts(); } void dd::Systems::BallSystem::UpdateEntity(double dt, EntityID entity, EntityID parent) @@ -272,13 +273,54 @@ bool dd::Systems::BallSystem::Contact(const Events::Contact &event) //std::cout << "Combo: " << ballComponent->Combo << std::endl; } else { - glm::vec2 reflectedVelocity = glm::reflect(ballVelocity, event.Normal); - ballTransform->Velocity = glm::vec3(reflectedVelocity, 0.f); + auto it = m_Contacts.find(ballEntity); + if (it == m_Contacts.end()) { + std::list normalList; + normalList.push_back(event.Normal); + m_Contacts[ballEntity] = normalList; + } else { + std::list normalList = it->second; + normalList.push_back(event.Normal); + m_Contacts[ballEntity] = normalList; + } + + //glm::vec2 reflectedVelocity = glm::reflect(ballVelocity, event.Normal); + //ballTransform->Velocity = glm::vec3(reflectedVelocity, 0.f); } return true; } + +void dd::Systems::BallSystem::ResolveContacts() +{ + + for (auto c : m_Contacts) { + int count = 0; + EntityID entity = c.first; + std::list contactNormals = c.second; + glm::vec2 finalNormal = glm::vec2(0.f); + for (auto it = contactNormals.begin(); it != contactNormals.end(); it++) { + finalNormal = finalNormal + (*it); + count++; + } + finalNormal = glm::normalize(finalNormal); + + if (count > 1) { + LOG_INFO("MultiCollision %i", count); + } + + auto transform = m_World->GetComponent(entity); + glm::vec2 velocity = glm::vec2(transform->Velocity.x, transform->Velocity.y); + glm::vec2 reflectedVelocity = glm::reflect(velocity, finalNormal); + transform->Velocity = glm::vec3(reflectedVelocity, 0.f); + + } + + + m_Contacts.clear(); +} + EntityID dd::Systems::BallSystem::CreateBall() { auto ent = m_World->CloneEntity(Ball()); @@ -352,3 +394,4 @@ bool dd::Systems::BallSystem::OnMultiBall(const dd::Events::MultiBall &event) return true; } + diff --git a/src/game/Physics/PhysicsSystem.cpp b/src/game/Physics/PhysicsSystem.cpp index b24f2d8..94461bd 100644 --- a/src/game/Physics/PhysicsSystem.cpp +++ b/src/game/Physics/PhysicsSystem.cpp @@ -254,7 +254,7 @@ void dd::Systems::PhysicsSystem::OnEntityRemoved(EntityID entity) return; } - LOG_INFO("Removing entity %i", entity); + //LOG_INFO("Removing entity %i", entity); it->second->GetWorld()->DestroyBody(it->second); m_BodiesToEntities.erase(it->second); m_EntitiesToBodies.erase(entity);