1
//////////////////// H FILE
#ifndef SPATIALHASHHANDLER_H
#define SPATIALHASHHANDLER_H
#include "GameObject.h"
#include <vector>
#include <unordered_set>
#include <unordered_map>
class SpatialHashHandler {
public:
SpatialHashHandler(float, float, float);
~SpatialHashHandler();
void clearBuckets();
void insertObject(GameObject*);
void getCollideObjects(vector<GameObject*>&, GameObject*);
private:
float width;
float height;
float cellSize;
int cols;
int rows;
int numCells;
unordered_map<int, vector<GameObject*>> buckets; // each vector in this vector is a "bucket" of GameObjects
const unordered_set<int> getID(GameObject*);
};
#endif
//////////////////// CPP FILE
#include "SpatialHashHandler.h"
SpatialHashHandler::SpatialHashHandler(float w, float h, float s) {
width = w;
height = h;
cellSize = s;
cols = width / cellSize;
rows = height / cellSize;
numCells = rows * cols;
buckets.reserve(numCells);
for (int i = 0; i < numCells; i++) {
buckets.emplace(i, vector<GameObject*>());
}
}
SpatialHashHandler::~SpatialHashHandler() {
clearBuckets();
}
void SpatialHashHandler::clearBuckets() {
for (auto& bucket : buckets) {
bucket.second.clear();
}
}
void SpatialHashHandler::insertObject(GameObject* object) {
unordered_set<int> IDs = getID(object);
unordered_set<int>::iterator it;
for (it = IDs.begin(); it != IDs.end(); it++) {
buckets[*(it)].push_back(object);
}
}
const unordered_set<int> SpatialHashHandler::getID(GameObject* object) {
unordered_set<int> bucketsObjectIsIn;
int w = object->Width();
int h = object->Height();
float minX = object->Position()->X();
float minY = object->Position()->Y();
float maxX = minX + w;
float maxY = minY + h;
bucketsObjectIsIn.insert(int(minX / cellSize) + cols * int(minY / cellSize)); // top left
bucketsObjectIsIn.insert(int(maxX / cellSize) + cols * int(minY / cellSize)); // top right
bucketsObjectIsIn.insert(int(maxX / cellSize) + cols * int(maxY / cellSize)); // bottom right
bucketsObjectIsIn.insert(int(minX / cellSize) + cols * int(maxY / cellSize)); // bottom left
return bucketsObjectIsIn;
}
void SpatialHashHandler::getCollideObjects(vector<GameObject*>& returnObjects, GameObject* object) {
unordered_set<GameObject*> uniqueObjects;
for (int id : getID(object)) {
for (GameObject* obj : buckets[id]) {
uniqueObjects.insert(obj);
}
}
returnObjects.assign(uniqueObjects.begin(), uniqueObjects.end());
}
For immediate assistance, please email our customer support: [email protected]