bool Level::isCollisions(Entity * e) { if(e->getBoundingBox() == NULL) return false; // Note : optimizable const AxisAlignedBB & box = *(e->getBoundingBox()); std::list<Collision> collisions; getCollisions(collisions, box, e); return !collisions.empty(); }
std::vector<Collision> OcTree::getCollisions(Node* n, std::vector<GameObject*> objects){ std::vector<Collision> collisions; //create a vector that is a copy of the objects provided combined with the objects in this node std::vector<GameObject*> colObjects; colObjects = n->objects; std::vector<GameObject*>::iterator it_end = colObjects.end(); colObjects.insert(colObjects.end(), objects.begin(), objects.end()); std::vector<GameObject*>::iterator ii, jj; GameObject* a; GameObject* b; //do an O(n^2) collision check between all objects in colObjects //TODO figure out how to properly do these nested loops without going out of bounds for (ii = n->objects.begin(); ii != n->objects.end(); ++ii){ a = *ii; //TODO only have dynamic objects check against other objects, but prevent double checks... //Possible solution, if objects come from 'above' don't have them check each other. //Compare n->objects against colObjects, and match the iterators. for (jj = ii + 1; jj != n->objects.end(); ++jj){ b = *jj; if(a == b || (!a->changedPosition && !b->changedPosition)) //don't compare objects against itself or if both objects haven't moved continue; if(a->getCollider()->collidesWith(b->getCollider(), a->cachedPosition, b->cachedPosition )){ Collision col; col.a = a; col.b = b; collisions.push_back(col); } collisionChecks++; } for (jj = objects.begin(); jj != objects.end(); ++jj){ b = *jj; if(a == b || (!a->changedPosition && !b->changedPosition)) //don't compare objects against itself or if both objects haven't moved continue; if(a->getCollider()->collidesWith(b->getCollider(), a->cachedPosition, b->cachedPosition )){ Collision col; col.a = a; col.b = b; collisions.push_back(col); } collisionChecks++; } } int kk; std::vector<GameObject*> list; for (kk = 0; kk < 8; kk++){ if(n->children[kk] == NULL) continue; for (ii = colObjects.begin(); ii != colObjects.end(); ++ii){ if (Bounding::intersects(&((*ii)->getCollider()->boundingBox), &(n->children[kk]->bounds))){ list.push_back(*ii); } } std::vector<Collision> result = getCollisions(n->children[kk], list); collisions.insert(collisions.end(), result.begin(), result.end()); list.clear(); } return collisions; }
std::vector<Collision> OcTree::getCollisions(std::vector<GameObject*> objects){ return getCollisions(root, objects); }
std::vector<Collision> OcTree::getCollisions(){ return getCollisions(root, std::vector<GameObject*>()); }