I'm trying to write a sort and sweep broadphase system, and I've run into some performance problems, during the overlap reporting stage.
My pair reporting code is where the bottleneck is:
The basic Idea, is to generate a temporary list of overlap pairs for every axis, then for every pair in X, check if the pair exists in Y and Z. Some extra checks are in the pair generation to deal with the stacking cube and containment edge cases. The pair generation code is as follows:
//temporary pair generation for X axis
for (unsigned int i = 0; i < mXExtents.size()-1; i++)
{
if (!mXExtents[i].mMax)
{
for (unsigned int j = i + 1; j < mXExtents.size(); j++)
{
if (mXExtents[j].mOwner->getID() == mXExtents[i].mOwner->getID())
{
break;
}
else
{
tempXPairs.push_back(new Pair(mXExtents[i].mOwner, mXExtents[j].mOwner));
}
}
}
}
//temporary pair generation for Y axis
for (unsigned int i = 0; i < mYExtents.size()-1; i ++)
{
if (!mYExtents[i].mMax)
{
for (unsigned int j = i + 1; j < mYExtents.size(); j++)
{
if (mYExtents[j].mOwner->getID() == mYExtents[i].mOwner->getID())
{
break;
}
else
{
tempYPairs.push_back(new Pair(mYExtents[i].mOwner, mYExtents[j].mOwner));
}
}
}
}
//temporary pair generation for Z axis
for (unsigned int i = 0; i < mZExtents.size()-1; i ++)
{
if (!mZExtents[i].mMax)
{
for (unsigned int j = i + 1; j < mZExtents.size(); j++)
{
if (mZExtents[j].mOwner->getID() == mZExtents[i].mOwner->getID())
{
break;
}
else
{
tempZPairs.push_back(new Pair(mZExtents[i].mOwner, mZExtents[j].mOwner));
}
}
}
}
The bottleneck, found through profiling, occurs when pairs are compared via the == operator. I suspect that this is due to many such checks being carried out, rather than the overhead of the check itself.
Pair reporting code as follows:
bool found = false;
//now search Y & Z temp storage for matching pairs
for (unsigned int i = 0; i < tempXPairs.size(); i++)
{
if (tempXPairs[i] != nullptr)
{
//search Y first
for (unsigned int j = 0; j < tempYPairs.size(); j++)
{
if (tempYPairs[j] != nullptr)
{
//match found in Y
if (*tempXPairs[i] == *tempYPairs[j])
{
//make a quick copy and stop searching
found = true;
delete tempYPairs[j];
tempYPairs[j] = nullptr;
break;
}
}
}
//element in Y found
if (found)
{
found = false;
//search Z temp list for a match
for (unsigned int j = 0; j < tempZPairs.size(); j++)
{
if (tempZPairs[j] == nullptr)
continue;
//match in Z found
if (*tempXPairs[i] == *tempZPairs[j])
{
//if we are at this stage then we have a triple match, so an overlap on all axes.
//add the pair to the manager
mPairManager->addpair(tempXPairs[i]);
//delete extranious pairs
delete tempZPairs[j];
tempZPairs[j] = nullptr;
//clear variables
tempXPairs[i] = nullptr;
//and end search
break;
}
}
//not found so get rid of all relevant pairs and move on to next in X list
delete tempXPairs[i];
tempXPairs[i] = nullptr;
}
else
{
delete tempXPairs[i];
tempXPairs[i] = nullptr;
}
}
}
//finally clear temp storage
for (unsigned int i = 0; i < tempXPairs.size(); i++)
{
if (tempXPairs[i] != nullptr)
{
delete tempXPairs[i];
}
}
for (unsigned int i = 0; i < tempYPairs.size(); i++)
{
if (tempYPairs[i] != nullptr)
{
delete tempYPairs[i];
}
}
for (unsigned int i = 0; i < tempZPairs.size(); i++)
{
if (tempZPairs[i] != nullptr)
{
delete tempZPairs[i];
}
}
The material I have read on sort and sweep/sweep and prune doesn't elaborate a fast way to deal with fast searching for duplicate pairs, or indeed, a way to search the other axes for equivelant pairs in an efficient manner. I'm clearly missing something, so I would appreciate any help that could be given.