-
Notifications
You must be signed in to change notification settings - Fork 0
/
CPhysicsSystem.cpp
146 lines (125 loc) · 5.95 KB
/
CPhysicsSystem.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#include "CPhysicsSystem.h"
extern ContactAddedCallback gContactAddedCallback;
CPhysicsSystem::CPhysicsSystem(entityx::ptr<entityx::EntityManager> em)
{
//ctor
emptr = (entityx::EntityManager*)em.get();
}
CPhysicsSystem::~CPhysicsSystem()
{
//dtor
}
bool CPhysicsSystem::contactCallbackFunction(btManifoldPoint& cp,const btCollisionObjectWrapper* obj1,int id0,int index0,const btCollisionObjectWrapper* obj2,int id1,int index1)
{
//std::cout << "collision" << std::endl;
static_assert(sizeof(void*) == sizeof(uint64_t), "need 64 bit pointers");
BulletCallbackHelper *helper = reinterpret_cast<BulletCallbackHelper*>(obj1->getCollisionObject()->getUserPointer());
entityx::EntityManager *em = (entityx::EntityManager*)(helper->entitymanager);
entityx::EventManager *ev = (entityx::EventManager*)(helper->eventmanager);
entityx::Entity ent = em->get(helper->entityid);
entityx::ptr<SoundComponent> sound = ent.component<SoundComponent>();
if(sound)
{
std::string snd = "/home/ersitzt/impact.wav";
sound->setSound(snd, true);
ev->emit<SoundEvent>(ent);
}
}
void CPhysicsSystem::configure(entityx::ptr<EventManager> event_manager)
{
std::cout << "CPhysicsSystem configure" << std::endl;
this->events = event_manager;
evptr = (entityx::EventManager*)this->events.get();
//Setup Bullet Physics
btBroadphaseInterface* broadphase = new btDbvtBroadphase();
btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration();
btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration);
btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver;
dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,broadphase,solver,collisionConfiguration);
dynamicsWorld->setGravity(btVector3(0,0,0));
// Ghost-Objects
btGhostPairCallback *ghostCall = new btGhostPairCallback();
dynamicsWorld->getBroadphase()->getOverlappingPairCache()->setInternalGhostPairCallback(ghostCall);
// Collision callback
gContactAddedCallback = CPhysicsSystem::contactCallbackFunction;
// entityx event we subscribe to
event_manager->subscribe<ComponentAddedEvent<PhysicsGhostComponent>>(*this);
event_manager->subscribe<ComponentAddedEvent<PhysicsComponent>>(*this);
}
void CPhysicsSystem::receive(const ComponentAddedEvent<PhysicsGhostComponent> &physicsghostcomponent)
{
entityx::Entity ent = physicsghostcomponent.entity;
entityx::ptr<PhysicsGhostComponent> gho = physicsghostcomponent.component;
entityx::ptr<PhysicsComponent> phys = ent.component<PhysicsComponent>();
if(phys)
{
// setUserPointer to BulletCallbackHelper which has a ref to the entitymanager an the id of the entity this component belongs to, so we can act on collisions
gho->ghost->setUserPointer(reinterpret_cast<void*>(new BulletCallbackHelper(ent.id(), emptr, evptr)));
}
dynamicsWorld->addCollisionObject(gho->ghost,btBroadphaseProxy::SensorTrigger,btBroadphaseProxy::AllFilter & ~btBroadphaseProxy::SensorTrigger);
}
void CPhysicsSystem::receive(const ComponentAddedEvent<PhysicsComponent> &physicscomponent)
{
entityx::ptr<PhysicsComponent> phys = physicscomponent.component;
entityx::Entity entity = physicscomponent.entity;
// setUserPointer to BulletCallbackHelper which has a ref to the entitymanager an the id of the entity this component belongs to, so we can act on collisions
phys->rigidBody->setUserPointer(reinterpret_cast<void*>(new BulletCallbackHelper(entity.id(), emptr, evptr)));
dynamicsWorld->addRigidBody(phys->rigidBody);
}
void CPhysicsSystem::update(entityx::ptr<EntityManager> es, entityx::ptr<EventManager> events, double dt)
{
#ifdef DEBUG
std::cout << "Physics Update" << std::endl;
#endif // DEBUG
dynamicsWorld->stepSimulation(1/60.f,10);
checkGhostCollision();
}
void CPhysicsSystem::checkGhostCollision()
{
int i;
for (i=0; i<dynamicsWorld->getCollisionObjectArray().size(); i++)
{
btCollisionObject* obj = dynamicsWorld->getCollisionObjectArray()[i];
btRigidBody* body = btRigidBody::upcast(obj);
btAlignedObjectArray < btCollisionObject* > objsInsidePairCachingGhostObject;
btAlignedObjectArray < btCollisionObject* >* pObjsInsideGhostObject = NULL;
btGhostObject* ghost = btGhostObject::upcast(obj);
if(ghost)
{
objsInsidePairCachingGhostObject.resize(0);
pObjsInsideGhostObject = &ghost->getOverlappingPairs();
#ifdef DEBUG
std::cout << ghost->getNumOverlappingObjects() << std::endl;
#endif // DEBUG
processGhostCollisions(*pObjsInsideGhostObject, ghost);
}
}
}
void CPhysicsSystem::processGhostCollisions(btAlignedObjectArray<btCollisionObject*>& obj, btGhostObject *ghost)
{
#ifdef DEBUG
std::cout << "Ghost Loop" << std::endl;
#endif // DEBUG
btTransform ghosttrans = ghost->getWorldTransform();
btVector3 ghostpos = ghosttrans.getOrigin();
for (int i=0; i<obj.size(); i++)
{
btCollisionObject* o = obj[i];
btRigidBody *b = btRigidBody::upcast(o);
btRigidBody *ghostbody = (btRigidBody*)ghost->getUserPointer();
BulletCallbackHelper *helper = reinterpret_cast<BulletCallbackHelper*>(b->getUserPointer());
entityx::EntityManager *mgr = (entityx::EntityManager*)(helper->entitymanager);
entityx::Entity ghostent = mgr->get(helper->entityid);
entityx::ptr<PhysicsGhostComponent> ghostcomp = ghostent.component<PhysicsGhostComponent>();
if(NULL != b && !ghostcomp)
{
btTransform trans;
b->getMotionState()->getWorldTransform(trans);
btVector3 origin = trans.getOrigin();
btScalar dist = origin.distance(ghostpos);
btVector3 impulsedirection = ghostpos - origin;
impulsedirection = impulsedirection.normalized();
b->applyCentralImpulse(impulsedirection * (100 / dist) * 0.2);
}
}
}