Merge branch 'Physics' into bugfix

Conflicts:
	include/Core/Engine.h
	include/Physics/PhysicsSystem.h
	src/game/Physics/PhysicsSystem.cpp
This commit is contained in:
viktorljung
2015-10-01 15:15:10 +02:00
9 changed files with 6019 additions and 383 deletions
+21
View File
@@ -0,0 +1,21 @@
# Blender MTL File: 'Sid.blend'
# Material Count: 2
newmtl Derp
Ns 96.078431
Ka 0.000000 0.000000 0.000000
Kd 0.800000 0.800000 0.800000
Ks 0.500000 0.500000 0.500000
Ni 1.000000
d 1.000000
illum 2
map_Kd SquidTexture.png
newmtl None
Ns 0
Ka 0.000000 0.000000 0.000000
Kd 0.8 0.8 0.8
Ks 0.8 0.8 0.8
d 1
illum 2
map_Kd SquidTexture.png
File diff suppressed because it is too large Load Diff
Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

+1
View File
@@ -138,6 +138,7 @@ public:
m_World->ComponentFactory.Register<Components::ParticleEmitter>(); m_World->ComponentFactory.Register<Components::ParticleEmitter>();
m_World->Initialize(); m_World->Initialize();
//PointLightTest //PointLightTest
{ {
auto t_Light = m_World->CreateEntity(); auto t_Light = m_World->CreateEntity();
+44 -78
View File
@@ -3,26 +3,33 @@
#include <unordered_map> #include <unordered_map>
#include "Core/CTransform.h" #include <Box2D/Box2D.h>
#include "Core/System.h" #include "Core/System.h"
#include "Core/World.h" #include "Core/World.h"
#include "Core/EventBroker.h" #include "Core/EventBroker.h"
#include "Core/CTemplate.h" #include "Core/CTemplate.h"
#include "Box2D/Box2D.h"
#include "Physics/CRectangleShape.h" #include "Physics/CRectangleShape.h"
#include "Physics/CCircleShape.h" #include "Physics/CCircleShape.h"
#include "Physics/CPhysics.h" #include "Physics/CPhysics.h"
#include "Physics/CWaterVolume.h" #include "Physics/CWaterVolume.h"
#include "Core/CTransform.h"
#include "Transform/TransformSystem.h"
#include "CRectangleShape.h"
#include "Physics/CPhysics.h"
#include "Physics/EContact.h" #include "Physics/EContact.h"
#include "Physics/ESetImpulse.h" #include "Physics/ESetImpulse.h"
#include "Physics/CParticle.h" #include "Physics/CParticle.h"
#include "Physics/CCircleShape.h"
#include "Physics/CParticleEmitter.h" #include "Physics/CParticleEmitter.h"
#include "Game/EPause.h" #include "Game/EPause.h"
#include "Game/CPad.h" #include "Game/CPad.h"
#include "Game/CPad.h"
#include "Game/CBall.h" #include "Game/CBall.h"
#include "Transform/TransformSystem.h" #include "Transform/TransformSystem.h"
#include "Rendering/CSprite.h" #include "Rendering/CSprite.h"
#include "Core/CTemplate.h"
namespace dd namespace dd
{ {
@@ -30,66 +37,66 @@ namespace dd
namespace Systems namespace Systems
{ {
class PhysicsSystem : public System class PhysicsSystem : public System
{ {
friend class ContractListener; friend class ContractListener;
public: public:
PhysicsSystem(World* world, std::shared_ptr<dd::EventBroker> eventBroker) PhysicsSystem(World* world, std::shared_ptr<dd::EventBroker> eventBroker)
: System(world, eventBroker) {} : System(world, eventBroker) { }
~PhysicsSystem(); ~PhysicsSystem();
EventRelay<PhysicsSystem, Events::SetImpulse> m_SetImpulse;
bool SetImpulse(const Events::SetImpulse &event);
void RegisterComponents(ComponentFactory* cf) override; void RegisterComponents(ComponentFactory* cf) override;
void Initialize() override; void Initialize() override;
// Called once per system every tick
void Update(double dt) override; void Update(double dt) override;
// Called once for every entity in the world every tick
void UpdateEntity(double dt, EntityID entity, EntityID parent) override; void UpdateEntity(double dt, EntityID entity, EntityID parent) override;
// Called when components are committed to an entity
void OnEntityCommit(EntityID entity) override; void OnEntityCommit(EntityID entity) override;
// Called when an entity is removed
void OnEntityRemoved(EntityID entity) override; void OnEntityRemoved(EntityID entity) override;
bool IsPaused() const { return m_Pause; }
void SetPause(const bool& pause) { m_Pause = pause; }
private: private:
b2Vec2 m_Gravity; struct Impulse
b2World* m_PhysicsWorld; {
double m_TimeStep; b2Body* Body;
double m_Accumulator; b2Vec2 Impulse;
b2Vec2 Point;
};
bool m_Pause = false; bool m_Pause = false;
dd::EventRelay<PhysicsSystem, dd::Events::Pause> m_EPause;
bool OnPause(const dd::Events::Pause &event);
int m_VelocityIterations, m_PositionIterations; b2Vec2 m_Gravity = b2Vec2(0.f, -9.82f);
b2World* m_PhysicsWorld = nullptr;
std::unordered_map<EntityID, b2Body*> m_EntitiesToBodies; float m_TimeStep = 1.f/60.f;
std::unordered_map<b2Body*, EntityID> m_BodiesToEntities; float m_Accumulator = 0.f;
int m_VelocityIterations = 6;
void CreateBody(EntityID entity); int m_PositionIterations = 2;
std::vector<b2ParticleSystem*> m_ParticleSystem; std::vector<b2ParticleSystem*> m_ParticleSystem;
std::vector<b2ParticleGroup*> t_ParticleGroup; std::vector<b2ParticleGroup*> t_ParticleGroup;
std::vector<std::unordered_map<EntityID, const b2ParticleHandle*>> m_EntitiesToParticleHandle; std::vector<std::unordered_map<EntityID, const b2ParticleHandle*>> m_EntitiesToParticleHandle;
std::vector<std::unordered_map<const b2ParticleHandle*, EntityID>> m_ParticleHandleToEntities; std::vector<std::unordered_map<const b2ParticleHandle*, EntityID>> m_ParticleHandleToEntities;
std::unordered_map<EntityID, b2Body*> m_EntitiesToBodies;
std::unordered_map<b2Body*, EntityID> m_BodiesToEntities;
b2ParticleSystem* CreateParticleSystem(float radius, float gravityScale);
void CreateBody(EntityID entity);
void SyncEntitiesWithBodies();
void SyncBodiesWithEntities();
void InitializeWater(); void InitializeWater();
void CreateParticleGroup(EntityID entity); void CreateParticleGroup(EntityID entity);
b2ParticleSystem* CreateParticleSystem(float radius, float gravityScale);
void CreateParticleEmitter(EntityID entity); void CreateParticleEmitter(EntityID entity);
void UpdateParticleEmitters(double dt); //TODO: Remove them and particles if needed. void UpdateParticleEmitters(double dt); //TODO: Remove them and particles if needed.
EventRelay<PhysicsSystem, Events::SetImpulse> m_SetImpulse;
bool SetImpulse(const Events::SetImpulse &event);
dd::EventRelay<PhysicsSystem, dd::Events::Pause> m_EPause;
bool OnPause(const dd::Events::Pause &event);
//TODO: Fill struct with info needed. //TODO: Fill struct with info needed.
struct ParticleEmitter struct ParticleEmitter
{ {
@@ -99,13 +106,6 @@ private:
}; };
ParticleEmitter m_ParticleEmitters; ParticleEmitter m_ParticleEmitters;
//TODO: Struct med listor är bättre än en lista med structs
struct Impulse
{
b2Body* Body;
b2Vec2 Impulse;
b2Vec2 Point;
};
std::list<Impulse> m_Impulses; std::list<Impulse> m_Impulses;
@@ -116,45 +116,10 @@ private:
ContactListener(PhysicsSystem* physicsSystem) ContactListener(PhysicsSystem* physicsSystem)
: m_PhysicsSystem(physicsSystem) { } : m_PhysicsSystem(physicsSystem) { }
void BeginContact(b2Contact* contact) void BeginContact(b2Contact* contact);
{ void EndContact(b2Contact* contact);
b2WorldManifold worldManifold; void PreSolve(b2Contact* contact, const b2Manifold* oldManifold);
void PostSolve(b2Contact* contact, const b2ContactImpulse* impulse);
contact->GetWorldManifold(&worldManifold);
Events::Contact e;
e.Entity1 = m_PhysicsSystem->m_BodiesToEntities[contact->GetFixtureA()->GetBody()];
e.Entity2 = m_PhysicsSystem->m_BodiesToEntities[contact->GetFixtureB()->GetBody()];
e.Normal = glm::normalize(glm::vec2(contact->GetManifold()->localNormal.x, contact->GetManifold()->localNormal.y));
e.SignificantNormal = glm::normalize((glm::abs(e.Normal.x) > glm::abs(e.Normal.y)) ? glm::vec2(e.Normal.x, 0) : glm::vec2(0, e.Normal.y));
m_PhysicsSystem->EventBroker->Publish(e);
}
void EndContact(b2Contact* contact)
{
}
void PreSolve(b2Contact* contact, const b2Manifold* oldManifold)
{
EntityID entityA = m_PhysicsSystem->m_BodiesToEntities[contact->GetFixtureA()->GetBody()];
EntityID entityB = m_PhysicsSystem->m_BodiesToEntities[contact->GetFixtureB()->GetBody()];
auto physicsComponentA = m_PhysicsSystem->m_World->GetComponent<Components::Physics>(entityA);
auto physicsComponentB = m_PhysicsSystem->m_World->GetComponent<Components::Physics>(entityB);
if (physicsComponentA != nullptr && physicsComponentB != nullptr) {
if (physicsComponentA->Calculate || physicsComponentB->Calculate) {
// Turn of collisions
contact->SetEnabled(false);
}
}
}
void PostSolve(b2Contact* contact, const b2ContactImpulse* impulse)
{
}
private: private:
PhysicsSystem* m_PhysicsSystem; PhysicsSystem* m_PhysicsSystem;
@@ -164,6 +129,7 @@ private:
}; };
} }
} }
#endif //DAYDREAM_PHYSICSSYSTEM_H #endif
+47
View File
@@ -0,0 +1,47 @@
#include "PrecompiledHeader.h"
#include "Physics/PhysicsSystem.h"
void dd::Systems::PhysicsSystem::ContactListener::BeginContact(b2Contact* contact)
{
b2WorldManifold worldManifold;
contact->GetWorldManifold(&worldManifold);
Events::Contact e;
e.Entity1 = m_PhysicsSystem->m_BodiesToEntities[contact->GetFixtureA()->GetBody()];
e.Entity2 = m_PhysicsSystem->m_BodiesToEntities[contact->GetFixtureB()->GetBody()];
e.Normal = glm::normalize(glm::vec2(contact->GetManifold()->localNormal.x, contact->GetManifold()->localNormal.y));
e.SignificantNormal = glm::normalize((glm::abs(e.Normal.x) > glm::abs(e.Normal.y)) ? glm::vec2(e.Normal.x, 0) : glm::vec2(0, e.Normal.y));
m_PhysicsSystem->EventBroker->Publish(e);
}
void dd::Systems::PhysicsSystem::ContactListener::EndContact(b2Contact* contact)
{
}
void dd::Systems::PhysicsSystem::ContactListener::PreSolve(b2Contact* contact, const b2Manifold* oldManifold)
{
EntityID entityA = m_PhysicsSystem->m_BodiesToEntities[contact->GetFixtureA()->GetBody()];
EntityID entityB = m_PhysicsSystem->m_BodiesToEntities[contact->GetFixtureB()->GetBody()];
auto physicsComponentA = m_PhysicsSystem->m_World->GetComponent<Components::Physics>(entityA);
auto physicsComponentB = m_PhysicsSystem->m_World->GetComponent<Components::Physics>(entityB);
if (physicsComponentA != nullptr && physicsComponentB != nullptr) {
if (physicsComponentA->Calculate || physicsComponentB->Calculate) {
// Turn of collisions
contact->SetEnabled(false);
}
}
}
void dd::Systems::PhysicsSystem::ContactListener::PostSolve(b2Contact* contact, const b2ContactImpulse* impulse)
{
}
+148 -122
View File
@@ -1,30 +1,19 @@
#include "PrecompiledHeader.h" #include "PrecompiledHeader.h"
#include "Physics/PhysicsSystem.h" #include "Physics/PhysicsSystem.h"
void dd::Systems::PhysicsSystem::RegisterComponents(ComponentFactory* cf) void dd::Systems::PhysicsSystem::RegisterComponents(ComponentFactory* cf)
{ {
cf->Register<Components::CircleShape>(); cf->Register<Components::CircleShape>();
//TODO: REGISTER PHYSICS COMPONENTS HERE
} }
void dd::Systems::PhysicsSystem::Initialize() void dd::Systems::PhysicsSystem::Initialize()
{ {
m_ContactListener = new ContactListener(this); m_ContactListener = new ContactListener(this);
m_Gravity = b2Vec2(0.f, -9.82f);
m_PhysicsWorld = new b2World(m_Gravity); m_PhysicsWorld = new b2World(m_Gravity);
m_TimeStep = 1.0/60.0;
m_VelocityIterations = 6;
m_PositionIterations = 2;
m_Accumulator = 0.0;
m_PhysicsWorld->SetContactListener(m_ContactListener); m_PhysicsWorld->SetContactListener(m_ContactListener);
InitializeWater(); InitializeWater();
EVENT_SUBSCRIBE_MEMBER(m_SetImpulse, PhysicsSystem::SetImpulse);
EVENT_SUBSCRIBE_MEMBER(m_SetImpulse, &PhysicsSystem::SetImpulse);
EVENT_SUBSCRIBE_MEMBER(m_EPause, &PhysicsSystem::OnPause); EVENT_SUBSCRIBE_MEMBER(m_EPause, &PhysicsSystem::OnPause);
} }
@@ -39,6 +28,11 @@ bool dd::Systems::PhysicsSystem::SetImpulse(const Events::SetImpulse &event)
{ {
b2Body* body = m_EntitiesToBodies[event.Entity]; b2Body* body = m_EntitiesToBodies[event.Entity];
if (body == nullptr) {
LOG_ERROR("Entity: %i, Tried to set an impulse on a body that does not exsist", event.Entity);
return false;
}
b2Vec2 impulse; b2Vec2 impulse;
impulse.x = event.Impulse.x; impulse.x = event.Impulse.x;
impulse.y = event.Impulse.y; impulse.y = event.Impulse.y;
@@ -47,112 +41,129 @@ bool dd::Systems::PhysicsSystem::SetImpulse(const Events::SetImpulse &event)
point.x = event.Point.x; point.x = event.Point.x;
point.y = event.Point.y; point.y = event.Point.y;
Impulse i; Impulse i;
i.Body = body; i.Body = body;
i.Impulse = impulse; i.Impulse = impulse;
i.Point = point; i.Point = point;
m_Impulses.push_back(i); m_Impulses.push_back(i);
return true; return true;
} }
void dd::Systems::PhysicsSystem::Update(double dt) { void dd::Systems::PhysicsSystem::SyncEntitiesWithBodies()
if (IsPaused()) { {
return;
}
m_Accumulator += dt; for (auto i : m_EntitiesToBodies) {
while (m_Accumulator >= m_TimeStep) { EntityID entity = i.first;
b2Body* body = i.second;
for (auto i : m_EntitiesToBodies) { if (body == nullptr) {
EntityID entity = i.first; LOG_ERROR("This body should not exist, please fix this");
b2Body *body = i.second; continue;
auto transformComponent = m_World->GetComponent<Components::Transform>(entity);
if (!transformComponent) {
continue;
LOG_ERROR("RigidBody with no TransformComponent");
}
auto physicsComponent = m_World->GetComponent<Components::Physics>(entity);
if (!physicsComponent) {
continue;
LOG_ERROR("RigidBody with no PhysicsComponent");
}
if (body == nullptr) {
LOG_ERROR("This body should not exist");
continue;
}
if (m_World->GetEntityParent(entity) == 0) { //TODO: Make this work with childs too
b2Vec2 position;
position.x = transformComponent->Position.x;
position.y = transformComponent->Position.y;
float angle = glm::eulerAngles(transformComponent->Orientation).z;
body->SetTransform(position, angle);
body->SetLinearVelocity(b2Vec2(transformComponent->Velocity.x, transformComponent->Velocity.y));
body->SetGravityScale(physicsComponent->GravityScale);
b2Filter filter;
filter.categoryBits = physicsComponent->Category;
filter.maskBits = physicsComponent->Mask;
body->GetFixtureList()->SetFilterData(filter);
}
} }
UpdateParticleEmitters(dt); auto transformComponent = m_World->GetComponent<Components::Transform>(entity);
if (! transformComponent) {
continue;
LOG_ERROR("RigidBody with no TransformComponent");
}
auto physicsComponent = m_World->GetComponent<Components::Physics>(entity);
if (! physicsComponent) {
continue;
LOG_ERROR("RigidBody with no PhysicsComponent");
}
if (m_World->GetEntityParent(entity) == 0) { //TODO: Make this work with childs too
b2Vec2 position;
position.x = transformComponent->Position.x;
position.y = transformComponent->Position.y;
float angle = glm::eulerAngles(transformComponent->Orientation).z;
body->SetTransform(position, angle);
body->SetLinearVelocity(b2Vec2(transformComponent->Velocity.x, transformComponent->Velocity.y));
body->SetGravityScale(physicsComponent->GravityScale);
b2Filter filter;
filter.categoryBits = physicsComponent->Category;
filter.maskBits = physicsComponent->Mask;
body->GetFixtureList()->SetFilterData(filter);
}
}
}
void dd::Systems::PhysicsSystem::SyncBodiesWithEntities()
{
for (auto i : m_BodiesToEntities) {
b2Body* body = i.first;
EntityID entity = i.second;
if (body == nullptr) {
LOG_ERROR("This body should not exist, please fix this");
continue;
}
auto transformComponent = m_World->GetComponent<Components::Transform>(entity);
if (! transformComponent) {
continue;
LOG_ERROR("RigidBody with no TransformComponent");
}
auto physicsComponent = m_World->GetComponent<Components::Physics>(entity);
if (! physicsComponent) {
continue;
LOG_ERROR("RigidBody with no PhysicsComponent");
}
auto parent = m_World->GetEntityParent(entity);
if (parent == 0) {
auto physicsComponent = m_World->GetComponent<Components::Physics>(entity);
if (physicsComponent->Calculate) { //TODO: REPLACE THIS WITH PARTICLE COLLISION FILTERS
transformComponent->Position.x = transformComponent->Position.x + (transformComponent->Velocity.x * m_TimeStep);
transformComponent->Position.y = transformComponent->Position.y + (transformComponent->Velocity.y * m_TimeStep);
} else {
b2Vec2 position = body->GetPosition();
transformComponent->Position.x = position.x;
transformComponent->Position.y = position.y;
float angle = body->GetAngle();
transformComponent->Orientation = glm::quat(glm::vec3(0, 0, angle));
b2Vec2 velocity = body->GetLinearVelocity();
transformComponent->Velocity.x = velocity.x;
transformComponent->Velocity.y = velocity.y;
}
}
}
}
void dd::Systems::PhysicsSystem::Update(double dt)
{
m_Accumulator += dt;
while(m_Accumulator >= m_TimeStep)
{
UpdateParticleEmitters(dt);
SyncEntitiesWithBodies();
//Apply Impulses Must be done after SyncEntitiesWithBodies
for (auto i : m_Impulses) { for (auto i : m_Impulses) {
i.Body->ApplyLinearImpulse(i.Impulse, i.Point, true); i.Body->ApplyLinearImpulse(i.Impulse, i.Point, true);
} }
m_Impulses.clear(); m_Impulses.clear();
//Update the PhysicsWorld
m_PhysicsWorld->Step(m_TimeStep, m_VelocityIterations, m_PositionIterations); m_PhysicsWorld->Step(m_TimeStep, m_VelocityIterations, m_PositionIterations);
SyncBodiesWithEntities();
for (auto i : m_EntitiesToBodies) {
EntityID entity = i.first;
b2Body *body = i.second;
if (body == nullptr) {
LOG_ERROR("This body should not exist");
continue;
}
auto transformComponent = m_World->GetComponent<Components::Transform>(entity);
if (!transformComponent)
continue;
auto parent = m_World->GetEntityParent(entity);
if (parent == 0) {
auto physicsComponent = m_World->GetComponent<Components::Physics>(entity);
if (physicsComponent->Calculate) { //TODO: REPLACE THIS WITH PARTICLE COLLISION FILTERS
transformComponent->Position.x =
transformComponent->Position.x + (transformComponent->Velocity.x * m_TimeStep);
transformComponent->Position.y =
transformComponent->Position.y + (transformComponent->Velocity.y * m_TimeStep);
}
else {
b2Vec2 position = body->GetPosition();
transformComponent->Position.x = position.x;
transformComponent->Position.y = position.y;
float angle = body->GetAngle();
transformComponent->Orientation = glm::quat(glm::vec3(0, 0, angle));
b2Vec2 velocity = body->GetLinearVelocity();
transformComponent->Velocity.x = velocity.x;
transformComponent->Velocity.y = velocity.y;
}
}
}
for ( int e = 0; e < m_EntitiesToParticleHandle.size(); e++) { for ( int e = 0; e < m_EntitiesToParticleHandle.size(); e++) {
b2Vec2 *positionBuffer = m_ParticleSystem[e]->GetPositionBuffer(); b2Vec2 *positionBuffer = m_ParticleSystem[e]->GetPositionBuffer();
for (auto i : m_EntitiesToParticleHandle[e]){ for (auto i : m_EntitiesToParticleHandle[e]) {
EntityID entity = i.first; EntityID entity = i.first;
b2ParticleHandle *particleH = i.second; b2ParticleHandle *particleH = i.second;
@@ -161,7 +172,7 @@ void dd::Systems::PhysicsSystem::Update(double dt) {
EntityID entityParent = m_World->GetEntityParent(entity); EntityID entityParent = m_World->GetEntityParent(entity);
glm::vec3 parentTransform = glm::vec3(0.f); glm::vec3 parentTransform = glm::vec3(0.f);
if(entityParent) { if (entityParent) {
auto tp = m_World->GetComponent<Components::Transform>(entityParent); auto tp = m_World->GetComponent<Components::Transform>(entityParent);
parentTransform = tp->Position; parentTransform = tp->Position;
} }
@@ -176,7 +187,6 @@ void dd::Systems::PhysicsSystem::Update(double dt) {
} }
} }
void dd::Systems::PhysicsSystem::UpdateEntity(double dt, EntityID entity, EntityID parent) void dd::Systems::PhysicsSystem::UpdateEntity(double dt, EntityID entity, EntityID parent)
{ {
@@ -188,10 +198,10 @@ bool dd::Systems::PhysicsSystem::OnPause(const dd::Events::Pause &event)
return false; return false;
} }
if (IsPaused()) { if (m_Pause) {
SetPause(false); m_Pause = false;
} else { } else {
SetPause(true); m_Pause = true;
} }
return true; return true;
} }
@@ -229,16 +239,19 @@ void dd::Systems::PhysicsSystem::OnEntityRemoved(EntityID entity)
} }
b2Body* body = m_EntitiesToBodies[entity]; b2Body* body = m_EntitiesToBodies[entity];
if (body == nullptr) {
if (body != nullptr) { LOG_ERROR("Trying to remove non-exsisting body, Entity: %i", entity);
m_EntitiesToBodies.erase(entity); return;
m_BodiesToEntities.erase(body);
m_PhysicsWorld->DestroyBody(body);
} }
m_EntitiesToBodies.erase(entity);
m_BodiesToEntities.erase(body);
body->GetWorld()->DestroyBody(body);
//delete body;
} }
void dd::Systems::PhysicsSystem::CreateBody(EntityID entity) void dd::Systems::PhysicsSystem::CreateBody(EntityID entity)
{ {
auto physicsComponent = m_World->GetComponent<Components::Physics>(entity); auto physicsComponent = m_World->GetComponent<Components::Physics>(entity);
@@ -247,7 +260,6 @@ void dd::Systems::PhysicsSystem::CreateBody(EntityID entity)
return; return;
} }
auto transformComponent = m_World->GetComponent<Components::Transform>(entity); auto transformComponent = m_World->GetComponent<Components::Transform>(entity);
if(!transformComponent) { if(!transformComponent) {
LOG_ERROR("No TransformComponent in CreateBody"); LOG_ERROR("No TransformComponent in CreateBody");
@@ -280,14 +292,11 @@ void dd::Systems::PhysicsSystem::CreateBody(EntityID entity)
auto circleComponent = m_World->GetComponent<Components::CircleShape>(entity); auto circleComponent = m_World->GetComponent<Components::CircleShape>(entity);
if (circleComponent) { if (circleComponent) {
pShape = new b2CircleShape(); pShape = new b2CircleShape();
pShape->m_radius = absoluteTransform.Scale.x;
if (absoluteTransform.Scale.x != absoluteTransform.Scale.y && absoluteTransform.Scale.y != absoluteTransform.Scale.z) {
LOG_WARNING("Circles has to be of uniform scale.");
}
pShape->m_radius = absoluteTransform.Scale.x/2; pShape->m_radius = absoluteTransform.Scale.x/2;
if (absoluteTransform.Scale.x != absoluteTransform.Scale.y && absoluteTransform.Scale.y != absoluteTransform.Scale.z) {
LOG_WARNING("Circles has to be of uniform scale. xScale has been used for radius");
}
} }
} }
@@ -297,20 +306,21 @@ void dd::Systems::PhysicsSystem::CreateBody(EntityID entity)
fixtureDef.filter.maskBits = physicsComponent->Mask; fixtureDef.filter.maskBits = physicsComponent->Mask;
if(physicsComponent->Static) {
body->CreateFixture(&fixtureDef); //Density kanske ska vara 0 p statiska kroppar
}
else {
fixtureDef.shape = pShape;
fixtureDef.density = 10.f;
fixtureDef.restitution = 1.0f;
fixtureDef.friction = 0.0f;
body->CreateFixture(&fixtureDef);
} fixtureDef.shape = pShape;
fixtureDef.density = 10.f;
fixtureDef.restitution = 1.0f;
fixtureDef.friction = 0.0f;
body->CreateFixture(&fixtureDef);
delete pShape; delete pShape;
if(physicsComponent->Static) {
body->SetType(b2BodyType::b2_staticBody);
} else if (! physicsComponent->Static) {
body->SetType(b2BodyType::b2_dynamicBody);
}
body->SetGravityScale(physicsComponent->GravityScale); body->SetGravityScale(physicsComponent->GravityScale);
m_EntitiesToBodies.insert(std::make_pair(entity, body)); m_EntitiesToBodies.insert(std::make_pair(entity, body));
@@ -448,8 +458,24 @@ b2ParticleSystem* dd::Systems::PhysicsSystem::CreateParticleSystem(float radius,
dd::Systems::PhysicsSystem::~PhysicsSystem() dd::Systems::PhysicsSystem::~PhysicsSystem()
{ {
for (auto i = m_BodiesToEntities.begin(); i != m_BodiesToEntities.end(); i++) {
b2Body* body = i->first;
body->GetWorld()->DestroyBody(body);
//delete body;
}
m_BodiesToEntities.clear();
m_EntitiesToBodies.clear();
m_Impulses.clear();
//TODO:REMOVE PARTICLE SYSTEMS
if (m_ContactListener != nullptr) { if (m_ContactListener != nullptr) {
delete m_ContactListener; delete m_ContactListener;
m_ContactListener = nullptr; m_ContactListener = nullptr;
} }
if (m_PhysicsWorld != nullptr) {
delete m_PhysicsWorld;
m_PhysicsWorld = nullptr;
}
} }
-183
View File
@@ -1,183 +0,0 @@
#include "PrecompiledHeader.h"
#include "Sound/SoundSystem.h"
dd::Systems::SoundSystem::~SoundSystem()
{
alcCloseDevice(m_Device);
};
void dd::Systems::SoundSystem::Initialize()
{
//initialize OpenAL
m_Device = alcOpenDevice(NULL);
ALCcontext* context;
if (m_Device) {
context = alcCreateContext(m_Device, NULL);
alcMakeContextCurrent(context);
}
else {
LOG_ERROR("OpenAL failed to initialize.");
}
alGetError();
//Subscribe to events
EVENT_SUBSCRIBE_MEMBER(m_EContact, &SoundSystem::OnContact);
EVENT_SUBSCRIBE_MEMBER(m_EPlaySFX, &SoundSystem::OnPlaySound);
EVENT_SUBSCRIBE_MEMBER(m_EStopSound, &SoundSystem::OnStopSound);
EVENT_SUBSCRIBE_MEMBER(m_EMasterVolume, &SoundSystem::OnMasterVolume);
<<<<<<< HEAD
//Todo: Move this
{
dd::Events::PlaySound e;
e.FilePath = "Sounds/BGM/under-the-sea-instrumental.wav";
e.IsAmbient = true;
EventBroker->Publish(e);
}
{
dd::Events::PlaySound e;
e.FilePath = "Sounds/BGM/water-flowing.wav";
e.Gain = 0.3f;
e.IsAmbient = true;
EventBroker->Publish(e);
}
=======
>>>>>>> origin/master
}
void dd::Systems::SoundSystem::Update(double dt)
{
//Clean up none-active sources
//Only used for SFX's. BGM's are handled on stop sound.
std::vector<ALuint> deleteList;
for (auto& item : m_SFXSourcesToBuffers) {
ALint sourceState;
alGetSourcei(item.first, AL_SOURCE_STATE, &sourceState);
if (sourceState == AL_STOPPED) {
deleteList.push_back(item.first);
}
}
for (int i = 0; i < deleteList.size(); i++) {
alDeleteSources(1, &deleteList[i]);
//alDeleteBuffers(1, &m_SourcesToBuffers[deleteList[i]]);
m_SFXSourcesToBuffers.erase(deleteList[i]);
}
}
ALuint dd::Systems::SoundSystem::CreateSource()
{
ALuint source;
alGenSources((ALuint)1, &source);
return source;
}
bool dd::Systems::SoundSystem::OnPlaySound(const dd::Events::PlaySound &event)
{
//Loading and binding sound buffer to source
Sound *sound = ResourceManager::Load<Sound>(event.FilePath);
if (sound == nullptr) {
return false;
}
ALuint source = CreateSource();
ALuint buffer = sound->Buffer();
alSourcei(source, AL_BUFFER, buffer);
//Sound settings
float relativeVolume = 1.f;
if (event.IsAmbient) {
alSourcei(source, AL_LOOPING, AL_TRUE);
relativeVolume = m_BGMMasterVolume;
m_BGMSourcesToBuffers[source] = sound;
}
else if (!event.IsAmbient)
{
m_SFXSourcesToBuffers[source] = sound;
alSourcei(source, AL_LOOPING, AL_FALSE);
relativeVolume = m_SFXMasterVolume;
}
alSourcef(source, AL_GAIN, (event.Gain * relativeVolume));
alSourcef(source, AL_PITCH, event.Pitch);
//Play
alSourcePlay(source);
return true;
}
bool dd::Systems::SoundSystem::OnStopSound(const dd::Events::StopSound &event)
{
ALuint itemToDeleted;
for (auto& item : m_BGMSourcesToBuffers)
{
if (item.second->Path() == event.FilePath) {
itemToDeleted = item.first;
break;
}
}
alSourceStop(itemToDeleted);
alDeleteSources(1, &itemToDeleted);
m_BGMSourcesToBuffers.erase(itemToDeleted);
//Should not happen because SFX's should be very short.
for (auto item : m_SFXSourcesToBuffers)
{
if (item.second->Path() == event.FilePath) {
alSourceStop(item.first);
return true;
}
}
return false;
}
bool dd::Systems::SoundSystem::OnMasterVolume(const dd::Events::MasterVolume &event)
{
//TODO: Make the Gain depend on the value given when stored.
//TODO: .. now it ONLY uses the master Gain
if (event.IsAmbient) {
m_BGMMasterVolume = event.Gain;
for (auto& item : m_BGMSourcesToBuffers)
{
alSourcef(item.first, AL_GAIN, event.Gain);
}
return true;
}
else if (!event.IsAmbient) {
m_SFXMasterVolume = event.Gain;
for (auto& item : m_SFXSourcesToBuffers)
{
alSourcef(item.first, AL_GAIN, event.Gain);
}
return true;
}
return false;
}
bool dd::Systems::SoundSystem::OnContact(const dd::Events::Contact &event)
{
//Check which entity has the collisionSound component.
auto collisionSound = m_World->GetComponent<Components::CollisionSound>(event.Entity1);
if (collisionSound == nullptr) {
collisionSound = m_World->GetComponent<Components::CollisionSound>(event.Entity2);
if (collisionSound == nullptr) {
//None of the entities had a collisionSound component.
return false;
}
}
//Send play-sound event
dd::Events::PlaySound e;
e.FilePath = collisionSound->FilePath;
e.IsAmbient = false;
EventBroker->Publish(e);
return true;
}
+51
View File
@@ -0,0 +1,51 @@
#include "PrecompiledHeader.h"
#include <boost/test/unit_test.hpp>
#include "Core/World.h"
#include "Core/EventBroker.h"
#include "Physics/PhysicsSystem.h"
#include "Transform/TransformSystem.h"
#include "Physics/CPhysics.h"
#include "Physics/CRectangleShape.h"
using namespace dd;
BOOST_AUTO_TEST_CASE(RemovePhysicsSystemTest)
{
// Setup world
std::shared_ptr<EventBroker> eventBroker = std::make_shared<EventBroker>();
World world(eventBroker);
world.SystemFactory.Register<Systems::TransformSystem>(
[this]() { return new Systems::TransformSystem(&world, eventBroker); });
world.AddSystem<Systems::TransformSystem>();
world.SystemFactory.Register<Systems::PhysicsSystem>(
[this]() { return new Systems::PhysicsSystem(&world, eventBroker); });
world.AddSystem<Systems::PhysicsSystem>();
world.ComponentFactory.Register<Components::RectangleShape>();
world.ComponentFactory.Register<Components::Physics>();
//Create entity
EntityID ent = world.CreateEntity();
auto transform = world.AddComponent<Components::Transform>(ent);
transform->Position = glm::vec3(20.f, 0.f, -10.f);
transform->Velocity = glm::vec3(1.f, 3.f, 0.f);
transform->Scale = glm::vec3(2.f, 5.f, 1.f);
auto physics = world.AddComponent<Components::Physics>(ent);
physics->Static = false;
physics->Calculate = true;
physics->Category = CollisionLayer::Type::Ball;
physics->Mask = CollisionLayer::Type::Brick | CollisionLayer::Type::Pad | CollisionLayer::Wall;
physics->GravityScale = 0.f;
auto rectangle = world.AddComponent<Components::RectangleShape>(ent);
}