Improved collisions with multiple objects in the same frame

This commit is contained in:
viktorljung
2015-10-06 19:41:00 +02:00
parent a2dc76051f
commit 65c01f9b8e
3 changed files with 55 additions and 8 deletions
+6 -2
View File
@@ -40,8 +40,7 @@ public:
~BallSystem(); ~BallSystem();
EventRelay<BallSystem, Events::Contact> m_Contact;
bool Contact(const Events::Contact &event);
void RegisterComponents(ComponentFactory *cf) override; void RegisterComponents(ComponentFactory *cf) override;
@@ -100,12 +99,17 @@ private:
EntityID m_Ball; EntityID m_Ball;
std::unordered_map<EntityID, std::list<glm::vec2>> m_Contacts;
void ResolveContacts();
dd::EventRelay<BallSystem, dd::Events::LifeLost> m_ELifeLost; dd::EventRelay<BallSystem, dd::Events::LifeLost> m_ELifeLost;
dd::EventRelay<BallSystem, dd::Events::MultiBallLost> m_EMultiBallLost; dd::EventRelay<BallSystem, dd::Events::MultiBallLost> m_EMultiBallLost;
dd::EventRelay<BallSystem, dd::Events::ResetBall> m_EResetBall; dd::EventRelay<BallSystem, dd::Events::ResetBall> m_EResetBall;
dd::EventRelay<BallSystem, dd::Events::MultiBall> m_EMultiBall; dd::EventRelay<BallSystem, dd::Events::MultiBall> m_EMultiBall;
dd::EventRelay<BallSystem, dd::Events::Pause> m_EPause; dd::EventRelay<BallSystem, dd::Events::Pause> m_EPause;
EventRelay<BallSystem, Events::Contact> m_Contact;
bool Contact(const Events::Contact &event);
bool OnLifeLost(const dd::Events::LifeLost &event); bool OnLifeLost(const dd::Events::LifeLost &event);
bool OnMultiBallLost(const dd::Events::MultiBallLost &event); bool OnMultiBallLost(const dd::Events::MultiBallLost &event);
bool OnResetBall(const dd::Events::ResetBall &event); bool OnResetBall(const dd::Events::ResetBall &event);
+48 -5
View File
@@ -25,12 +25,12 @@ void dd::Systems::BallSystem::Initialize()
auto ent = m_World->CreateEntity(); auto ent = m_World->CreateEntity();
std::shared_ptr<Components::Transform> transform = m_World->AddComponent<Components::Transform>(ent); std::shared_ptr<Components::Transform> transform = m_World->AddComponent<Components::Transform>(ent);
transform->Position = glm::vec3(-0.f, 50.26f, -10.f); 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); transform->Velocity = glm::vec3(0.f, 0.f, 0.f);
auto model = m_World->AddComponent<Components::Model>(ent); auto model = m_World->AddComponent<Components::Model>(ent);
model->ModelFile = "Models/Test/Ball/Ballopus.obj"; model->ModelFile = "Models/Test/Ball/Sid.obj";
std::shared_ptr<Components::CircleShape> circleShape = m_World->AddComponent<Components::CircleShape>(ent); std::shared_ptr<Components::CircleShape> circleShape = m_World->AddComponent<Components::CircleShape>(ent);
circleShape->Radius = 0.5f; circleShape->Radius = 0.2f;
std::shared_ptr<Components::Ball> ball = m_World->AddComponent<Components::Ball>(ent); std::shared_ptr<Components::Ball> ball = m_World->AddComponent<Components::Ball>(ent);
ball->Speed = 5.f; ball->Speed = 5.f;
std::shared_ptr<Components::Physics> physics = m_World->AddComponent<Components::Physics>(ent); std::shared_ptr<Components::Physics> physics = m_World->AddComponent<Components::Physics>(ent);
@@ -68,6 +68,7 @@ void dd::Systems::BallSystem::Update(double dt)
Events::GameOver e; Events::GameOver e;
EventBroker->Publish(e); EventBroker->Publish(e);
} }
ResolveContacts();
} }
void dd::Systems::BallSystem::UpdateEntity(double dt, EntityID entity, EntityID parent) 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; //std::cout << "Combo: " << ballComponent->Combo << std::endl;
} }
else { else {
glm::vec2 reflectedVelocity = glm::reflect(ballVelocity, event.Normal); auto it = m_Contacts.find(ballEntity);
ballTransform->Velocity = glm::vec3(reflectedVelocity, 0.f); if (it == m_Contacts.end()) {
std::list<glm::vec2> normalList;
normalList.push_back(event.Normal);
m_Contacts[ballEntity] = normalList;
} else {
std::list<glm::vec2> 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; return true;
} }
void dd::Systems::BallSystem::ResolveContacts()
{
for (auto c : m_Contacts) {
int count = 0;
EntityID entity = c.first;
std::list<glm::vec2> 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<Components::Transform>(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() EntityID dd::Systems::BallSystem::CreateBall()
{ {
auto ent = m_World->CloneEntity(Ball()); auto ent = m_World->CloneEntity(Ball());
@@ -352,3 +394,4 @@ bool dd::Systems::BallSystem::OnMultiBall(const dd::Events::MultiBall &event)
return true; return true;
} }
+1 -1
View File
@@ -254,7 +254,7 @@ void dd::Systems::PhysicsSystem::OnEntityRemoved(EntityID entity)
return; return;
} }
LOG_INFO("Removing entity %i", entity); //LOG_INFO("Removing entity %i", entity);
it->second->GetWorld()->DestroyBody(it->second); it->second->GetWorld()->DestroyBody(it->second);
m_BodiesToEntities.erase(it->second); m_BodiesToEntities.erase(it->second);
m_EntitiesToBodies.erase(entity); m_EntitiesToBodies.erase(entity);