Skip to content

Commit

Permalink
Split collision methods for performance
Browse files Browse the repository at this point in the history
  • Loading branch information
maurhofer-ubique committed Jan 24, 2024
1 parent c5edfc6 commit 33b4ea9
Showing 1 changed file with 107 additions and 65 deletions.
172 changes: 107 additions & 65 deletions shared/public/CollisionGrid.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,42 +100,11 @@ class CollisionGrid {
}
}

bool colliding = false;
for (int16_t y = indexRange.yMin; y <= indexRange.yMax; y++) {
for (int16_t x = indexRange.xMin; x <= indexRange.xMax; x++) {
for (const auto &rect : gridRects[y][x]) {
if (CollisionUtil::checkRectCollision(projectedRectangle, rect)) {
if (alwaysInsert) {
colliding = true;
break;
} else {
return 1;
}
}
}
for (const auto &circle : gridCircles[y][x]) {
if (CollisionUtil::checkRectCircleCollision(projectedRectangle, circle)) {
if (alwaysInsert) {
colliding = true;
break;
} else {
return 1;
}
}
}
}
}

for (int16_t y = indexRange.yMin; y <= indexRange.yMax; y++) {
for (int16_t x = indexRange.xMin; x <= indexRange.xMax; x++) {
gridRects[y][x].push_back(projectedRectangle);
}
}
if (rectangle.contentHash != 0 && rectangle.symbolSpacing > 0) {
spacedRects[rectangle.contentHash].push_back(projectedRectangle);
if (alwaysInsert) {
return checkRectInsertAlways(rectangle, projectedRectangle, indexRange);
} else {
return checkRectInsertOnCollision(rectangle, projectedRectangle, indexRange);
}

return colliding ? 1 : 0;
}

/**
Expand All @@ -149,7 +118,7 @@ class CollisionGrid {
}

std::vector<std::tuple<CircleF, IndexRange, size_t, int16_t>> projectedCircles;
for (const auto &circle : circles) {
for (const auto &circle: circles) {
auto projectedCircle = getProjectedCircle(circle);
IndexRange indexRange = getIndexRangeForCircle(projectedCircle);
if (indexRange.isValid(numCellsX - 1, numCellsY - 1)) {
Expand All @@ -162,60 +131,106 @@ class CollisionGrid {
return 2;
}

bool colliding = false;
for (const auto &[projectedCircle, indexRange, contentHash, symbolSpacing] : projectedCircles) {
for (const auto &[projectedCircle, indexRange, contentHash, symbolSpacing]: projectedCircles) {

if (contentHash != 0 && symbolSpacing > 0) {
const auto &equalRects = spacedRects.find(contentHash);
if (equalRects != spacedRects.end()) {
for (const auto &other : equalRects->second) {
for (const auto &other: equalRects->second) {
// Assume equal symbol spacing for all primitives with matching content
if (CollisionUtil::checkRectCircleCollision(other, projectedCircle, symbolSpacing)) {
if (alwaysInsert) {
colliding = true;
break;
} else {
return 1;
}
return 1;

}
}
}
const auto &equalCircles = spacedCircles.find(contentHash);
if (equalCircles != spacedCircles.end()) {
for (const auto &other : equalCircles->second) {
for (const auto &other: equalCircles->second) {
// Assume equal symbol spacing for all primitives with matching content
if (CollisionUtil::checkCircleCollision(projectedCircle, other, symbolSpacing)) {
if (alwaysInsert) {
colliding = true;
break;
} else {
return 1;
}
return 1;
}
}
}
}
}

if (alwaysInsert) {
return checkCirclesInsertAlways(circles, projectedCircles);
} else {
return checkCirclesInsertOnCollision(circles, projectedCircles);
}
}

private:
uint8_t checkRectInsertOnCollision(const CollisionRectF &rectangle, const RectF &projectedRectangle, const IndexRange &indexRange) {
for (int16_t y = indexRange.yMin; y <= indexRange.yMax; y++) {
for (int16_t x = indexRange.xMin; x <= indexRange.xMax; x++) {
for (const auto &rect: gridRects[y][x]) {
if (CollisionUtil::checkRectCollision(projectedRectangle, rect)) {
return 1;
}
}
for (const auto &circle: gridCircles[y][x]) {
if (CollisionUtil::checkRectCircleCollision(projectedRectangle, circle)) {
return 1;
}
}
}
}

for (int16_t y = indexRange.yMin; y <= indexRange.yMax; y++) {
for (int16_t x = indexRange.xMin; x <= indexRange.xMax; x++) {
gridRects[y][x].push_back(projectedRectangle);
}
}
if (rectangle.contentHash != 0 && rectangle.symbolSpacing > 0) {
spacedRects[rectangle.contentHash].push_back(projectedRectangle);
}

return 0;
}

uint8_t checkRectInsertAlways(const CollisionRectF &rectangle, const RectF &projectedRectangle, const IndexRange &indexRange) {
bool colliding = false;
for (int16_t y = indexRange.yMin; y <= indexRange.yMax; y++) {
for (int16_t x = indexRange.xMin; x <= indexRange.xMax; x++) {
if (!colliding) {
for (const auto &rect: gridRects[y][x]) {
if (CollisionUtil::checkRectCollision(projectedRectangle, rect)) {
colliding = true;
}
}
for (const auto &circle: gridCircles[y][x]) {
if (CollisionUtil::checkRectCircleCollision(projectedRectangle, circle)) {
colliding = true;
}
}
}
gridRects[y][x].push_back(projectedRectangle);
}
}

if (rectangle.contentHash != 0 && rectangle.symbolSpacing > 0) {
spacedRects[rectangle.contentHash].push_back(projectedRectangle);
}

return colliding ? 1 : 0;
}

uint8_t checkCirclesInsertOnCollision(const std::vector<CollisionCircleF> &circles, const std::vector<std::tuple<CircleF, IndexRange, size_t, int16_t>> &projectedCircles) {
for (const auto &[projectedCircle, indexRange, contentHash, symbolSpacing] : projectedCircles) {
for (int16_t y = indexRange.yMin; y <= indexRange.yMax; y++) {
for (int16_t x = indexRange.xMin; x <= indexRange.xMax; x++) {
for (const auto &rect : gridRects[y][x]) {
if (CollisionUtil::checkRectCircleCollision(rect, projectedCircle)) {
if (alwaysInsert) {
colliding = true;
break;
} else {
return 1;
}
return 1;
}
}
for (const auto &circle : gridCircles[y][x]) {
if (CollisionUtil::checkCircleCollision(projectedCircle, circle)) {
if (alwaysInsert) {
colliding = true;
break;
} else {
return 1;
}
return 1;
}
}
}
Expand All @@ -233,10 +248,37 @@ class CollisionGrid {
}
}

return 0;
}

uint8_t checkCirclesInsertAlways(const std::vector<CollisionCircleF> &circles, const std::vector<std::tuple<CircleF, IndexRange, size_t, int16_t>> &projectedCircles) {
bool colliding = false;
for (const auto &[projectedCircle, indexRange, contentHash, symbolSpacing]: projectedCircles) {
for (int16_t y = indexRange.yMin; y <= indexRange.yMax; y++) {
for (int16_t x = indexRange.xMin; x <= indexRange.xMax; x++) {
if (!colliding) {
for (const auto &rect: gridRects[y][x]) {
if (CollisionUtil::checkRectCircleCollision(rect, projectedCircle)) {
colliding = true;
}
}
for (const auto &circle: gridCircles[y][x]) {
if (CollisionUtil::checkCircleCollision(projectedCircle, circle)) {
colliding = true;
}
}
}
gridCircles[y][x].push_back(projectedCircle);
}
}
if (contentHash != 0 && symbolSpacing > 0) {
spacedCircles[contentHash].push_back(projectedCircle);
}
}

return colliding ? 1 : 0;
}

private:
RectF getProjectedRectangle(const CollisionRectF &rectangle) {
temp2[0] = rectangle.x - rectangle.anchorX; // move x to the anchor
temp2[1] = rectangle.y - rectangle.anchorY;
Expand Down

0 comments on commit 33b4ea9

Please sign in to comment.