From a674295a830abdde514113464dcde28add72f83d Mon Sep 17 00:00:00 2001 From: ViktorLjung Date: Thu, 22 May 2014 22:05:06 +0200 Subject: [PATCH] Collisionfilters --- src/Components/Physics.h | 22 +++++- src/Events/DisableCollisions.h | 18 +++++ src/Events/EnableCollisions.h | 18 +++++ src/GameWorld.cpp | 24 ++++--- src/Systems/PhysicsSystem.cpp | 69 ++++++++++++++++--- src/Systems/PhysicsSystem.h | 22 ++++-- src/Systems/TankSteeringSystem.cpp | 53 ++++++++++++++ src/Systems/TankSteeringSystem.h | 2 + src/World.cpp | 14 ++-- vs11/Returngeance/Returngeance.vcxproj | 2 + .../Returngeance/Returngeance.vcxproj.filters | 6 ++ 11 files changed, 218 insertions(+), 32 deletions(-) create mode 100644 src/Events/DisableCollisions.h create mode 100644 src/Events/EnableCollisions.h diff --git a/src/Components/Physics.h b/src/Components/Physics.h index fe3358f..8fd3f69 100644 --- a/src/Components/Physics.h +++ b/src/Components/Physics.h @@ -9,12 +9,32 @@ namespace Components struct Physics : Component { Physics() - : Mass(1.f), Static(false), Phantom(false){} + : Mass(1.f), Static(false), Phantom(false), CalculateCenterOfMass(true), CenterOfMass(glm::vec3(0)), InitialLinearVelocity(glm::vec3(0)), InitialAngularVelocity(glm::vec3(0)), + LinearDamping(0.f), AngularDamping(0.05f), GravityFactor(1.f), Friction(0.5f), Restitution(0.4f), MaxLinearVelocity(200.f), MaxAngularVelocity(200.f), + CollisionLayer(0), CollisionSystemGroup(0), CollisionSubSystemId(0), CollisionSubSystemDontCollideWith(0){} float Mass; bool Static; bool Phantom; + bool CalculateCenterOfMass; + glm::vec3 CenterOfMass; + glm::vec3 InitialLinearVelocity; + glm::vec3 InitialAngularVelocity; + float LinearDamping; + float AngularDamping; + float GravityFactor; + float Friction; + float Restitution; + float MaxLinearVelocity; + float MaxAngularVelocity; + + int CollisionLayer; + int CollisionSystemGroup; + int CollisionSubSystemId; + int CollisionSubSystemDontCollideWith; + + virtual Physics* Clone() const override { return new Physics(*this); } }; diff --git a/src/Events/DisableCollisions.h b/src/Events/DisableCollisions.h new file mode 100644 index 0000000..e41b7dd --- /dev/null +++ b/src/Events/DisableCollisions.h @@ -0,0 +1,18 @@ +#ifndef Events_DisableCollisions_h__ +#define Events_DisableCollisions_h__ +#include "Entity.h" +#include "EventBroker.h" + + namespace Events +{ + + struct DisableCollisions : Event + { + int Layer1; + int Layer2; + + }; + +} + +#endif // Events_DisableCollisions_h__ \ No newline at end of file diff --git a/src/Events/EnableCollisions.h b/src/Events/EnableCollisions.h new file mode 100644 index 0000000..cf81d46 --- /dev/null +++ b/src/Events/EnableCollisions.h @@ -0,0 +1,18 @@ +#ifndef Events_EnableCollisions_h__ +#define Events_EnableCollisions_h__ +#include "Entity.h" +#include "EventBroker.h" + +namespace Events +{ + + struct EnableCollisions : Event + { + int Layer1; + int Layer2; + + }; + +} + +#endif // Events_EnableCollisions_h__ \ No newline at end of file diff --git a/src/GameWorld.cpp b/src/GameWorld.cpp index 18af9e8..96f094b 100755 --- a/src/GameWorld.cpp +++ b/src/GameWorld.cpp @@ -15,6 +15,9 @@ void GameWorld::Initialize() BindGamepadAxis(Gamepad::Axis::LeftX, "horizontal", 1.f); BindGamepadAxis(Gamepad::Axis::LeftY, "vertical", 1.f); + BindKey(GLFW_KEY_1, "EnableCollisions", 1.f); + BindKey(GLFW_KEY_2, "DisableCollisions", 1.f); + BindKey(GLFW_KEY_UP, "barrel_rotation", 1.f); BindKey(GLFW_KEY_DOWN, "barrel_rotation", -1.f); BindKey(GLFW_KEY_LEFT, "tower_rotation", -1.f); @@ -98,7 +101,7 @@ void GameWorld::Initialize() auto physics = AddComponent(ground); physics->Mass = 10; physics->Static = true; - + physics->CollisionLayer = 0; auto groundshape = CreateEntity(ground); auto transformshape = AddComponent(groundshape); @@ -251,6 +254,8 @@ void GameWorld::Initialize() auto physics = AddComponent(tank); physics->Mass = 63000 - 16000; physics->Static = false; + physics->CollisionLayer = 2; + auto vehicle = AddComponent(tank); vehicle->MaxTorque = 36000.f; vehicle->MaxSteeringAngle = 90.f; @@ -551,7 +556,7 @@ void GameWorld::Initialize() } CommitEntity(wheel); - auto entity = CreateEntity(tank); + /*auto entity = CreateEntity(tank); auto transformComponent = AddComponent(entity); transformComponent->Position = glm::vec3(-2,-1.7,2.0); transformComponent->Scale = glm::vec3(3,3,3); @@ -574,7 +579,7 @@ void GameWorld::Initialize() spriteComponent->SpriteFile = "Models/Textures/Sprites/Dust.png"; emitterComponent->ParticleTemplate = particleEntity; - CommitEntity(particleEntity); + CommitEntity(particleEntity);*/ } { @@ -636,7 +641,7 @@ void GameWorld::Initialize() } CommitEntity(wheel); - auto entity = CreateEntity(tank); + /*auto entity = CreateEntity(tank); auto transformComponent = AddComponent(entity); transformComponent->Position = glm::vec3(2,-1.7,2.0); transformComponent->Scale = glm::vec3(3,3,3); @@ -658,7 +663,7 @@ void GameWorld::Initialize() auto spriteComponent = AddComponent(particleEntity); spriteComponent->SpriteFile = "Models/Textures/Sprites/Dust.png"; emitterComponent->ParticleTemplate = particleEntity; - CommitEntity(particleEntity); + CommitEntity(particleEntity);*/ } #pragma endregion @@ -673,6 +678,7 @@ void GameWorld::Initialize() auto physics = AddComponent(tank); physics->Mass = 63000 - 16000; physics->Static = false; + physics->CollisionLayer = 1; auto vehicle = AddComponent(tank); vehicle->MaxTorque = 36000.f; vehicle->MaxSteeringAngle = 90.f; @@ -974,7 +980,7 @@ void GameWorld::Initialize() } CommitEntity(wheel); - auto entity = CreateEntity(tank); + /*auto entity = CreateEntity(tank); auto transformComponent = AddComponent(entity); transformComponent->Position = glm::vec3(2,-1.7,2.0); transformComponent->Scale = glm::vec3(3,3,3); @@ -996,7 +1002,7 @@ void GameWorld::Initialize() spriteComponent->SpriteFile = "Models/Textures/Sprites/Dust.png"; emitterComponent->ParticleTemplate = particleEntity; - CommitEntity(particleEntity); + CommitEntity(particleEntity);*/ } { @@ -1058,7 +1064,7 @@ void GameWorld::Initialize() } CommitEntity(wheel); - auto entity = CreateEntity(tank); + /*auto entity = CreateEntity(tank); auto transformComponent = AddComponent(entity); transformComponent->Position = glm::vec3(-2,-1.7,2.0); transformComponent->Scale = glm::vec3(3,3,3); @@ -1080,7 +1086,7 @@ void GameWorld::Initialize() spriteComponent->SpriteFile = "Models/Textures/Sprites/Dust.png"; emitterComponent->ParticleTemplate = particleEntity; - CommitEntity(particleEntity); + CommitEntity(particleEntity);*/ } #pragma endregion CommitEntity(tank); diff --git a/src/Systems/PhysicsSystem.cpp b/src/Systems/PhysicsSystem.cpp index 04a9b15..59b2e43 100644 --- a/src/Systems/PhysicsSystem.cpp +++ b/src/Systems/PhysicsSystem.cpp @@ -36,7 +36,9 @@ void Systems::PhysicsSystem::Initialize() EVENT_SUBSCRIBE_MEMBER(m_ESetVelocity, &Systems::PhysicsSystem::OnSetVelocity); EVENT_SUBSCRIBE_MEMBER(m_EApplyForce, &Systems::PhysicsSystem::OnApplyForce); EVENT_SUBSCRIBE_MEMBER(m_EApplyPointImpulse, &Systems::PhysicsSystem::OnApplyPointImpulse); - + EVENT_SUBSCRIBE_MEMBER(m_EEnableCollisions, &Systems::PhysicsSystem::OnEnableCollisions); + EVENT_SUBSCRIBE_MEMBER(m_EDisableCollisions, &Systems::PhysicsSystem::OnDisableCollisions); + hkMemorySystem::FrameInfo finfo(6000 * 1024); // Allocate 6MB of Physics solver buffer hkMemoryRouter* memoryRouter = hkMemoryInitUtil::initDefault(hkMallocAllocator::m_defaultMallocAllocator, finfo); hkBaseSystem::init(memoryRouter, HavokErrorReport); @@ -102,14 +104,20 @@ void Systems::PhysicsSystem::Initialize() m_Context = new hkpPhysicsContext; hkpPhysicsContext::registerAllPhysicsProcesses(); // all the physics viewers m_Context->addWorld(m_PhysicsWorld); // add the physics world so the viewers can see it - SetupVisualDebugger(m_Context); - + m_CollisionFilter = new hkpGroupFilter(); + m_PhysicsWorld->setCollisionFilter( m_CollisionFilter ); m_PhysicsWorld->unmarkForWrite(); m_collisionResolution = new MyCollisionResolution(this); } - + + { + Events::DisableCollisions e; + e.Layer1 = 1; + e.Layer2 = 2; + EventBroker->Publish(e); + } } void Systems::PhysicsSystem::RegisterComponents(ComponentFactory* cf) @@ -298,8 +306,21 @@ void Systems::PhysicsSystem::OnEntityCommit( EntityID entity ) rigidBodyInfo.m_rotation.set(rotation(0), rotation(1), rotation(2), rotation(3)); rigidBodyInfo.m_inertiaTensor = massProperties.m_inertiaTensor; - //rigidBodyInfo.m_centerOfMass = massProperties.m_centerOfMass; //HACK: CENTER OF MASS ALWAYS IN THE CENTER + if(physicsComponent->CalculateCenterOfMass) + physicsComponent->CenterOfMass = HKVECTOR4_TO_GLMVEC3(massProperties.m_centerOfMass); + rigidBodyInfo.m_centerOfMass = GLMVEC3_TO_HKVECTOR4(physicsComponent->CenterOfMass); rigidBodyInfo.m_mass = massProperties.m_mass; + rigidBodyInfo.m_linearVelocity = GLMVEC3_TO_HKVECTOR4(physicsComponent->InitialLinearVelocity); + rigidBodyInfo.m_angularVelocity = GLMVEC3_TO_HKVECTOR4(physicsComponent->InitialAngularVelocity); + rigidBodyInfo.m_linearDamping = physicsComponent->LinearDamping; + rigidBodyInfo.m_angularDamping = physicsComponent->AngularDamping; + rigidBodyInfo.m_gravityFactor = physicsComponent->GravityFactor; + rigidBodyInfo.m_linearDamping = physicsComponent->LinearDamping; + rigidBodyInfo.m_friction = physicsComponent->Friction; + rigidBodyInfo.m_restitution = physicsComponent->Restitution; + rigidBodyInfo.m_maxLinearVelocity = physicsComponent->MaxLinearVelocity; + rigidBodyInfo.m_maxAngularVelocity = physicsComponent->MaxAngularVelocity; + rigidBodyInfo.m_collisionFilterInfo = hkpGroupFilter::calcFilterInfo(physicsComponent->CollisionLayer, physicsComponent->CollisionSystemGroup, physicsComponent->CollisionSubSystemId, physicsComponent->CollisionSubSystemDontCollideWith); } // Create RigidBody hkpRigidBody* rigidBody = new hkpRigidBody(rigidBodyInfo); @@ -386,10 +407,24 @@ void Systems::PhysicsSystem::OnEntityCommit( EntityID entity ) hkQuaternion rotation = GLMQUAT_TO_HKQUATERNION(absoluteTransform.Orientation); rigidBodyInfo.m_position.set(position(0), position(1), position(2), position(3)); rigidBodyInfo.m_rotation.set(rotation(0), rotation(1), rotation(2), rotation(3)); - + rigidBodyInfo.m_inertiaTensor = massProperties.m_inertiaTensor; - //rigidBodyInfo.m_centerOfMass = massProperties.m_centerOfMass; //HACK: CENTER OF MASS ALWAYS IN THE CENTER + if(physicsComponent->CalculateCenterOfMass) + physicsComponent->CenterOfMass = HKVECTOR4_TO_GLMVEC3(massProperties.m_centerOfMass); + rigidBodyInfo.m_centerOfMass = GLMVEC3_TO_HKVECTOR4(physicsComponent->CenterOfMass); rigidBodyInfo.m_mass = massProperties.m_mass; + rigidBodyInfo.m_linearVelocity = GLMVEC3_TO_HKVECTOR4(physicsComponent->InitialLinearVelocity); + rigidBodyInfo.m_angularVelocity = GLMVEC3_TO_HKVECTOR4(physicsComponent->InitialAngularVelocity); + rigidBodyInfo.m_linearDamping = physicsComponent->LinearDamping; + rigidBodyInfo.m_angularDamping = physicsComponent->AngularDamping; + rigidBodyInfo.m_gravityFactor = physicsComponent->GravityFactor; + rigidBodyInfo.m_linearDamping = physicsComponent->LinearDamping; + rigidBodyInfo.m_friction = physicsComponent->Friction; + rigidBodyInfo.m_restitution = physicsComponent->Restitution; + rigidBodyInfo.m_maxLinearVelocity = physicsComponent->MaxLinearVelocity; + rigidBodyInfo.m_maxAngularVelocity = physicsComponent->MaxAngularVelocity; + rigidBodyInfo.m_collisionFilterInfo = hkpGroupFilter::calcFilterInfo(physicsComponent->CollisionLayer, physicsComponent->CollisionSystemGroup, physicsComponent->CollisionSubSystemId, physicsComponent->CollisionSubSystemDontCollideWith); + } // Create RigidBody hkpRigidBody* rigidBody = new hkpRigidBody(rigidBodyInfo); @@ -402,8 +437,6 @@ void Systems::PhysicsSystem::OnEntityCommit( EntityID entity ) shape->removeReference(); rigidBody->removeReference(); - - } } @@ -595,3 +628,21 @@ void Systems::PhysicsSystem::OnEntityRemoved( EntityID entity ) m_PhysicsWorld->unmarkForWrite(); } } + +bool Systems::PhysicsSystem::OnEnableCollisions( const Events::EnableCollisions &e ) +{ + m_CollisionFilter->enableCollisionsBetween(e.Layer1, e.Layer2); + m_PhysicsWorld->markForWrite(); + m_PhysicsWorld->setCollisionFilter(m_CollisionFilter); + m_PhysicsWorld->unmarkForWrite(); + return true; +} + +bool Systems::PhysicsSystem::OnDisableCollisions( const Events::DisableCollisions &e ) +{ + m_CollisionFilter->disableCollisionsBetween(e.Layer1, e.Layer2); + m_PhysicsWorld->markForWrite(); + m_PhysicsWorld->setCollisionFilter(m_CollisionFilter); + m_PhysicsWorld->unmarkForWrite(); + return true; +} diff --git a/src/Systems/PhysicsSystem.h b/src/Systems/PhysicsSystem.h index 5f71187..1e173db 100644 --- a/src/Systems/PhysicsSystem.h +++ b/src/Systems/PhysicsSystem.h @@ -78,6 +78,9 @@ #include "Components/TankShell.h" #include +#include "Events/EnableCollisions.h" +#include "Events/DisableCollisions.h" + namespace Systems { class PhysicsSystem : public System @@ -95,20 +98,18 @@ public: EntityID entity1 = m_PhysicsSystem->m_RigidBodyEntities[event.getBody(0)]; EntityID entity2 = m_PhysicsSystem->m_RigidBodyEntities[event.getBody(1)]; - m_PhysicsSystem->m_PhysicsWorld->unmarkForRead(); Events::Collision e; e.Entity1 = entity1; e.Entity2 = entity2; - m_PhysicsSystem->EventBroker->Publish(e); - m_PhysicsSystem->m_PhysicsWorld->markForRead(); + //m_PhysicsSystem->EventBroker->Publish(e); } - + private: Systems::PhysicsSystem* m_PhysicsSystem; }; friend class MyCollisionResolution; - /*class PhantomCallbackShape: public hkpPhantomCallbackShape + class PhantomCallbackShape: public hkpPhantomCallbackShape { public: @@ -124,6 +125,8 @@ public: glm::vec3 impulse; impulse = HKVECTOR4_TO_GLMVEC3(hkpGetRigidBody(collidableA)->getPosition()) - HKVECTOR4_TO_GLMVEC3(hkpGetRigidBody(collidableB)->getPosition()); e.Impulse = impulse; + + m_PhysicsSystem->EventBroker->Publish(e); } virtual void phantomLeaveEvent( const hkpCollidable* collidableA, const hkpCollidable* collidableB ) @@ -135,7 +138,7 @@ public: Systems::PhysicsSystem* m_PhysicsSystem; }; friend class PhantomCallbackShape; - */ + PhysicsSystem(World* world, std::shared_ptr<::EventBroker> eventBroker) : System(world, eventBroker) { } @@ -152,6 +155,7 @@ public: private: double m_Accumulator; hkpWorld* m_PhysicsWorld; + hkpGroupFilter* m_CollisionFilter; // Events EventRelay m_ETankSteer; @@ -163,6 +167,12 @@ private: EventRelay m_EApplyPointImpulse; bool OnApplyPointImpulse(const Events::ApplyPointImpulse &event); + EventRelay m_EEnableCollisions; + bool OnEnableCollisions(const Events::EnableCollisions &e); + EventRelay m_EDisableCollisions; + bool OnDisableCollisions(const Events::DisableCollisions &e); + + void SetUpPhysicsState(EntityID entity, EntityID parent); void TearDownPhysicsState(EntityID entity, EntityID parent); diff --git a/src/Systems/TankSteeringSystem.cpp b/src/Systems/TankSteeringSystem.cpp index db98e97..7fca5c2 100644 --- a/src/Systems/TankSteeringSystem.cpp +++ b/src/Systems/TankSteeringSystem.cpp @@ -114,6 +114,25 @@ bool Systems::TankSteeringSystem::OnCollision( const Events::Collision &e ) health2->health -= tankShell1->Damage; } + { + auto hitSphere = m_World->CreateEntity(); + auto transformHit = m_World->AddComponent(hitSphere); + transformHit->Position = transform->Position; + + auto physics = m_World->AddComponent(hitSphere); + physics->Static = false; + physics->Phantom = true; + + { + auto shape = m_World->CreateEntity(hitSphere); + auto transformHit = m_World->AddComponent(shape); + auto sphereShape = m_World->AddComponent(shape); + sphereShape->Radius = 40.f*0.5f; //HACK: + m_World->CommitEntity(shape); + } + m_World->CommitEntity(hitSphere); + } + m_World->RemoveEntity(e.Entity1); } @@ -128,6 +147,26 @@ bool Systems::TankSteeringSystem::OnCollision( const Events::Collision &e ) health1->health -= tankShell1->Damage; } + { + auto hitSphere = m_World->CreateEntity(); + auto transformHit = m_World->AddComponent(hitSphere); + transformHit->Position = transform->Position; + + auto physics = m_World->AddComponent(hitSphere); + physics->Static = false; + physics->Phantom = true; + + { + auto shape = m_World->CreateEntity(hitSphere); + auto transformHit = m_World->AddComponent(shape); + auto sphereShape = m_World->AddComponent(shape); + sphereShape->Radius = 40.f*0.5f; //HACK: + m_World->CommitEntity(shape); + } + m_World->CommitEntity(hitSphere); + } + + m_World->RemoveEntity(e.Entity2); } } @@ -183,6 +222,20 @@ bool Systems::TankSteeringSystem::TankSteeringInputController::OnCommand(const E m_Shoot = val > 0; } + else if(event.Command == "EnableCollisions") + { + Events::EnableCollisions e; + e.Layer1 = 1; + e.Layer2 = 2; + EventBroker->Publish(e); + } + else if(event.Command == "DisableCollisions") + { + Events::DisableCollisions e; + e.Layer1 = 1; + e.Layer2 = 2; + EventBroker->Publish(e); + } return true; } diff --git a/src/Systems/TankSteeringSystem.h b/src/Systems/TankSteeringSystem.h index bde07ab..a3bcb61 100644 --- a/src/Systems/TankSteeringSystem.h +++ b/src/Systems/TankSteeringSystem.h @@ -22,6 +22,8 @@ #include "Components/TankShell.h" #include "Components/SphereShape.h" +#include "Events/EnableCollisions.h" +#include "Events/DisableCollisions.h" namespace Systems { diff --git a/src/World.cpp b/src/World.cpp index d9d36be..d0c3817 100755 --- a/src/World.cpp +++ b/src/World.cpp @@ -83,12 +83,6 @@ void World::RemoveEntity(EntityID entity) m_EntitiesToRemove.push_back(pair.first); } } - // Trigger events - for (auto pair : m_Systems) - { - auto system = pair.second; - system->OnEntityRemoved(entity); - } } void World::ProcessEntityRemovals() @@ -111,8 +105,14 @@ void World::ProcessEntityRemovals() m_ComponentsOfType[type].remove(component); } m_EntityComponents.erase(entity); - RecycleEntityID(entity); + + // Trigger events + for (auto pair : m_Systems) + { + auto system = pair.second; + system->OnEntityRemoved(entity); + } } m_EntitiesToRemove.clear(); } diff --git a/vs11/Returngeance/Returngeance.vcxproj b/vs11/Returngeance/Returngeance.vcxproj index 7a1c955..b9ad781 100755 --- a/vs11/Returngeance/Returngeance.vcxproj +++ b/vs11/Returngeance/Returngeance.vcxproj @@ -166,6 +166,8 @@ + + diff --git a/vs11/Returngeance/Returngeance.vcxproj.filters b/vs11/Returngeance/Returngeance.vcxproj.filters index 5dc5595..3619c2d 100755 --- a/vs11/Returngeance/Returngeance.vcxproj.filters +++ b/vs11/Returngeance/Returngeance.vcxproj.filters @@ -406,6 +406,12 @@ Physics\Components + + Physics\Events + + + Physics\Events +