void PhysicsWorld::FindAllCollisions() { contactManager.numOldContacts = contactManager.numContacts; assert(contactManager.numOldContacts < MaxNumContacts ); memcpy(contactManager.oldContacts, contactManager.contacts, contactManager.numOldContacts * sizeof(Contact)); contactManager.numContacts = 0; /* O(n^2) collsion detection ( or worse LOL ) Check all fixtures vs all fixtures for collisions, We dont collide fixtures that are from the same body */ for ( size_t i = 0; i < numBodies; i++ ) { for ( size_t j = i + 1; j < numBodies; j++ ) { if ( (bodies[i]->type != eDynamic && bodies[j]->type != eDynamic) ) { continue; } if ( contactManager.contactFilter && !contactManager.contactFilter->ShouldCollide(bodies[i], bodies[j]) ) { continue; } Fixture *fi = bodies[i]->GetFixtureList(); while ( fi ) { Fixture *fj = bodies[j]->GetFixtureList(); while ( fj ) { if ( fi->IsSensor( ) || fj->IsSensor( ) ) { if ( CheckOverlap(fi->GetShape(), bodies[i]->GetPosition(), fj->GetShape(), bodies[j]->GetPosition()) ) { contactManager.contactListener->OnSensor(fi, fj); } } else { // check collision and add to the contact list if they intersect contactManager.AddPair(fi, fj); } fj = fj->GetNext(); } fi = fi->GetNext(); } } } contactManager.MergeContacts(); }
Fixture * World::QueryPoint(const Vector2 &point) const { for(int i = 0; i < entities.size(); i++) { for(Fixture *f = entities[i]->body.GetFixtureList(); f != 0; f = f->GetNext()) { if(f->GetShape()->TestPoint(point, entities[i]->body.GetPosition())) { return f; } } } return 0; }
void Graphics::Draw(Renderer *renderer) { Fixture *fixture = owner->body.GetFixtureList(); while ( fixture ) { if(visible) { if ( fixture->GetType() == eCircle ) { renderer->DrawTexturedQuad( texture, owner->body.GetPosition() + static_cast<Circle*>(fixture->GetShape())->localPos, static_cast<Circle*>(fixture->GetShape())->radius * 2.0f, static_cast<Circle*>(fixture->GetShape())->radius * 2.0f, angle, Vector2(0.0f, 0.0f), //owner->body.GetPosition() + static_cast<Circle*>(fixture->GetShape())->localPos, flipX, flipY, color ); } else if ( fixture->GetType() == eAABox ) { Vector2 minExt = static_cast<AABox*>(fixture->GetShape())->minExt; Vector2 maxExt = static_cast<AABox*>(fixture->GetShape())->maxExt; Vector2 boxSize = maxExt - minExt; renderer->DrawTexturedQuad( texture, owner->body.GetPosition() + boxSize/2.0f, boxSize.x, boxSize.y, 0.0f, owner->body.GetPosition() + boxSize/2.0f, flipX, flipY, color ); } else if ( fixture->GetType() == eCapsule ) { Vector2 pos0 = static_cast<Capsule*>(fixture->GetShape())->localPos0 + owner->body.GetPosition(); Vector2 pos1 = static_cast<Capsule*>(fixture->GetShape())->localPos1 + owner->body.GetPosition(); float radius = static_cast<Capsule*>(fixture->GetShape())->radius; Vector2 normal = normalize(pos1-pos0); Vector2 tangent = Vector2(-normal.y, normal.x); Vector2 verts[4]; verts[0] = pos0 - normal * radius - tangent * radius; verts[1] = pos1 + normal * radius - tangent * radius; verts[2] = pos1 + normal * radius + tangent * radius; verts[3] = pos0 - normal * radius + tangent * radius; Vector2 texCoords[4]; if ( !flipX ) { texCoords[0] = Vector2(0.0f, 0.0f); texCoords[1] = Vector2(1.0f, 0.0f); texCoords[2] = Vector2(1.0f, 1.0f); texCoords[3] = Vector2(0.0f, 1.0f); } else { texCoords[2] = Vector2(0.0f, 0.0f); texCoords[0] = Vector2(1.0f, 0.0f); texCoords[1] = Vector2(1.0f, 1.0f); texCoords[3] = Vector2(0.0f, 1.0f); } glColor4f(color.r, color.g, color.b, color.a); renderer->DrawTexturedQuad(texture, verts, texCoords); } } if ( drawShape ) { fixture->GetShape()->Draw(*renderer, owner->body.GetPosition()); } fixture = fixture->GetNext(); } }
void BoxScreen::drawBody (const BodyP &b) { for (Fixture *f = b->GetFixtureList(); f; f = f->GetNext()) { drawShape (b,f->GetShape()); } }