From f2e7d2eaacfa54ce4541dd270fb5a419cb4d9383 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Sun, 4 Feb 2024 06:10:07 -0800 Subject: [PATCH] Use vector instead of forward_list for dpGrid also swap contains in for find != end on an associative container since we are in c++20 now :) --- dPhysics/dpEntity.cpp | 2 +- dPhysics/dpGrid.cpp | 80 ++++++++++++++++++++----------------------- dPhysics/dpGrid.h | 10 +++--- 3 files changed, 44 insertions(+), 48 deletions(-) diff --git a/dPhysics/dpEntity.cpp b/dPhysics/dpEntity.cpp index 70bddb40..cbe3f5e8 100644 --- a/dPhysics/dpEntity.cpp +++ b/dPhysics/dpEntity.cpp @@ -76,7 +76,7 @@ void dpEntity::CheckCollision(dpEntity* other) { return; } - bool wasFound = (m_CurrentlyCollidingObjects.find(other->GetObjectID()) != m_CurrentlyCollidingObjects.end()); + bool wasFound = m_CurrentlyCollidingObjects.contains(other->GetObjectID()); bool isColliding = m_CollisionShape->IsColliding(other->GetShape()); diff --git a/dPhysics/dpGrid.cpp b/dPhysics/dpGrid.cpp index 1704e068..f498c491 100644 --- a/dPhysics/dpGrid.cpp +++ b/dPhysics/dpGrid.cpp @@ -8,24 +8,14 @@ dpGrid::dpGrid(int numCells, int cellSize) { CELL_SIZE = cellSize; m_DeleteGrid = true; - //fill x - for (int i = 0; i < NUM_CELLS; i++) { - m_Cells.push_back(std::vector>()); - } - - //fill z - for (int i = 0; i < NUM_CELLS; i++) { - for (int i = 0; i < NUM_CELLS; i++) { - m_Cells[i].push_back(std::forward_list()); - } - } + m_Cells.resize(NUM_CELLS, std::vector>(NUM_CELLS)); } dpGrid::~dpGrid() { if (!this->m_DeleteGrid) return; for (auto& x : m_Cells) { //x - for (auto& y : x) { //y - for (auto en : y) { + for (auto& z : x) { //y + for (auto en : z) { if (!en) continue; delete en; en = nullptr; @@ -39,13 +29,12 @@ void dpGrid::Add(dpEntity* entity) { int cellX = (int)std::round(entity->m_Position.x) / dpGrid::CELL_SIZE + NUM_CELLS / 2; int cellZ = (int)std::round(entity->m_Position.z) / dpGrid::CELL_SIZE + NUM_CELLS / 2; - if (cellX < 0) cellX = 0; - if (cellZ < 0) cellZ = 0; - if (cellX >= NUM_CELLS) cellX = NUM_CELLS - 1; - if (cellZ >= NUM_CELLS) cellZ = NUM_CELLS - 1; + // Clamp values to the range [0, NUM_CELLS - 1] + std::clamp(cellX, 0, NUM_CELLS - 1); + std::clamp(cellZ, 0, NUM_CELLS - 1); //Add to cell: - m_Cells[cellX][cellZ].push_front(entity); + m_Cells[cellX][cellZ].push_back(entity); //To verify that the object isn't gargantuan: if (entity->GetScale() >= CELL_SIZE * 2 || entity->GetIsGargantuan()) @@ -59,23 +48,27 @@ void dpGrid::Move(dpEntity* entity, float x, float z) { int cellX = (int)std::round(x) / dpGrid::CELL_SIZE + NUM_CELLS / 2; int cellZ = (int)std::round(z) / dpGrid::CELL_SIZE + NUM_CELLS / 2; - if (cellX < 0) cellX = 0; - if (cellZ < 0) cellZ = 0; - if (cellX >= NUM_CELLS) cellX = NUM_CELLS - 1; - if (cellZ >= NUM_CELLS) cellZ = NUM_CELLS - 1; + // Clamp values to the range [0, NUM_CELLS - 1] + std::clamp(cellX, 0, NUM_CELLS - 1); + std::clamp(cellZ, 0, NUM_CELLS - 1); - if (oldCellX < 0) oldCellX = 0; - if (oldCellZ < 0) oldCellZ = 0; - if (oldCellX >= NUM_CELLS) oldCellX = NUM_CELLS - 1; - if (oldCellZ >= NUM_CELLS) oldCellZ = NUM_CELLS - 1; + std::clamp(oldCellX, 0, NUM_CELLS - 1); + std::clamp(oldCellZ, 0, NUM_CELLS - 1); if (oldCellX == cellX && oldCellZ == cellZ) return; - //Remove from perv cell: - m_Cells[oldCellX][oldCellZ].remove(entity); + //Remove from prev cell: + auto& cell = m_Cells[oldCellX][oldCellZ]; + + // For speed, find the single match and swap it with the last element, then pop_back. + auto toRemove = std::find(cell.begin(), cell.end(), entity); + if (toRemove != cell.end()) { + *toRemove = cell.back(); + cell.pop_back(); + } //Add to the new cell - m_Cells[cellX][cellZ].push_front(entity); + m_Cells[cellX][cellZ].push_back(entity); } void dpGrid::Delete(dpEntity* entity) { @@ -83,15 +76,18 @@ void dpGrid::Delete(dpEntity* entity) { int oldCellX = (int)std::round(entity->m_Position.x) / dpGrid::CELL_SIZE + NUM_CELLS / 2; int oldCellZ = (int)std::round(entity->m_Position.z) / dpGrid::CELL_SIZE + NUM_CELLS / 2; - if (oldCellX < 0) oldCellX = 0; - if (oldCellZ < 0) oldCellZ = 0; - if (oldCellX >= NUM_CELLS) oldCellX = NUM_CELLS - 1; - if (oldCellZ >= NUM_CELLS) oldCellZ = NUM_CELLS - 1; + // Clamp values to the range [0, NUM_CELLS - 1] + std::clamp(oldCellX, 0, NUM_CELLS - 1); + std::clamp(oldCellZ, 0, NUM_CELLS - 1); - m_Cells[oldCellX][oldCellZ].remove(entity); + auto& cell = m_Cells[oldCellX][oldCellZ]; + auto toRemove = std::find(cell.begin(), cell.end(), entity); + if (toRemove != cell.end()) { + *toRemove = cell.back(); + cell.pop_back(); + } - if (m_GargantuanObjects.find(entity->m_ObjectID) != m_GargantuanObjects.end()) - m_GargantuanObjects.erase(entity->m_ObjectID); + m_GargantuanObjects.erase(entity->m_ObjectID); if (entity) delete entity; entity = nullptr; @@ -100,8 +96,8 @@ void dpGrid::Delete(dpEntity* entity) { void dpGrid::Update(float deltaTime) { //Pre-update: for (auto& x : m_Cells) { //x - for (auto& y : x) { //y - for (auto en : y) { + for (auto& z : x) { //y + for (auto en : z) { if (!en) continue; en->PreUpdate(); } @@ -110,8 +106,8 @@ void dpGrid::Update(float deltaTime) { //Actual collision detection update: for (int x = 0; x < NUM_CELLS; x++) { - for (int y = 0; y < NUM_CELLS; y++) { - HandleCell(x, y, deltaTime); + for (int z = 0; z < NUM_CELLS; z++) { + HandleCell(x, z, deltaTime); } } } @@ -157,7 +153,7 @@ void dpGrid::HandleCell(int x, int z, float deltaTime) { HandleEntity(en, other); } - for (auto other : m_GargantuanObjects) - HandleEntity(en, other.second); + for (auto& [id, entity] : m_GargantuanObjects) + HandleEntity(en, entity); } } diff --git a/dPhysics/dpGrid.h b/dPhysics/dpGrid.h index 229e7449..39a9cfe7 100644 --- a/dPhysics/dpGrid.h +++ b/dPhysics/dpGrid.h @@ -1,8 +1,7 @@ #pragma once -#include -#include -#include #include +#include + #include "dCommonVars.h" class dpEntity; @@ -30,7 +29,8 @@ public: */ void SetDeleteGrid(bool value) { this->m_DeleteGrid = value; }; - std::vector>> GetCells() { return this->m_Cells; }; + // Intentional copy since this is only used when we delete this class to re-create it. + std::vector>> GetCells() { return this->m_Cells; }; private: void HandleEntity(dpEntity* entity, dpEntity* other); @@ -38,7 +38,7 @@ private: private: //cells on X, cells on Y for that X, then another vector that contains the entities within that cell. - std::vector>> m_Cells; + std::vector>> m_Cells; std::map m_GargantuanObjects; bool m_DeleteGrid = true; };