Commit 0f084a95 authored by BRAMAS Berenger's avatar BRAMAS Berenger

Add a way to know if two morton index are neighbor in constant time (a few instruction)

parent 8c299582
......@@ -86,7 +86,7 @@ public:
return currentMaxZ;
}
virtual MortonIndex getIndex(const int inX, const int inY, const int inZ) override{
MortonIndex getIndex(const int inX, const int inY, const int inZ) override{
return FTreeCoordinate(inX+coord.getX(), inY+coord.getY(), inZ+coord.getZ()).getMortonIndex(level);
}
};
......@@ -192,9 +192,44 @@ public:
return currentMaxZ;
}
virtual MortonIndex getIndex(const int inX, const int inY, const int inZ) override{
MortonIndex getIndex(const int inX, const int inY, const int inZ) override{
return (mindexes[inX+1]&flagX) | (mindexes[inY+1]&flagY) | (mindexes[inZ+1]&flagZ);
}
bool areNeighbors(const MortonIndex mv1, const MortonIndex mv2){
bool cellsAreNeighbor = true;
const MortonIndex flags[3] = { flagX, flagY, flagZ };
for(int idx = 0; idx < 3; ++idx){
const MortonIndex v1 = (mv1 & flags[idx]);
const MortonIndex v2 = (mv2 & flags[idx]);
if( (v1 == v2) || ((v1^v2) == 1) ){
// Are neighbor
}
else{
MortonIndex firstBit = 0;
asm("bsf %1,%0" : "=r"(firstBit) : "r"(FMath::Max(v1,v2)));
const MortonIndex highMask = ((((~MortonIndex(0))>>(firstBit+1))<<(firstBit+1)) & flags[idx]);
if((v1&highMask) != (v2&highMask)){
cellsAreNeighbor = false;
break;
}
const MortonIndex lowMask = ((~((~MortonIndex(0))<<firstBit)) & flags[idx]);
if((FMath::Min(v1,v2)&lowMask) != lowMask){
cellsAreNeighbor = false;
break;
}
// Are neighbors
}
}
return cellsAreNeighbor;
}
};
#endif // FNEIGHBORINDEXES_HPP
......
......@@ -59,6 +59,8 @@ class TestIndexes : public FUTester<TestIndexes> {
uassert(xbox + idxX == neighCoord.getX());
uassert(ybox + idxY == neighCoord.getY());
uassert(zbox + idxZ == neighCoord.getZ());
uassert(bitsindex.areNeighbors(mindex, neigh));
}
}
}
......@@ -102,6 +104,11 @@ class TestIndexes : public FUTester<TestIndexes> {
uassert(xbox + idxX == neighCoord.getX());
uassert(ybox + idxY == neighCoord.getY());
uassert(zbox + idxZ == neighCoord.getZ());
uassert(bitsindex.areNeighbors(mindex, neigh));
if(bitsindex.areNeighbors(mindex, neigh) == false){
printf("Stop here\n");// TODO remove
}
}
}
}
......@@ -142,6 +149,8 @@ class TestIndexes : public FUTester<TestIndexes> {
uassert(xbox + idxX == neighCoord.getX());
uassert(ybox + idxY == neighCoord.getY());
uassert(zbox + idxZ == neighCoord.getZ());
uassert(bitsindex.areNeighbors(mindex, neigh));
}
}
}
......@@ -152,12 +161,35 @@ class TestIndexes : public FUTester<TestIndexes> {
}
}
void Neighbors(){
{
const int idxLevel = 5;
const MortonIndex limit = FMath::pow2(idxLevel)*3L;
for(MortonIndex idxV1 = 1 ; idxV1 < limit ; ++idxV1){
FBitsNeighborIndex bitsindex(idxV1, idxLevel);
const FTreeCoordinate coord1(idxV1, idxLevel);
for(MortonIndex idxV2 = 0 ; idxV2 < limit ; ++idxV2){
const bool isneig = bitsindex.areNeighbors(idxV1, idxV2);
const FTreeCoordinate coord2(idxV2, idxLevel);
const bool isreallyneig = (FMath::Abs(coord1.getX()-coord2.getX()) <= 1)
&& (FMath::Abs(coord1.getY()-coord2.getY()) <= 1)
&& (FMath::Abs(coord1.getZ()-coord2.getZ()) <= 1);
uassert(isneig == isreallyneig);
}
}
}
}
// set test
void SetTests(){
AddTest(&TestIndexes::MortonLimite,"Test NeighborIndexes at limits");
AddTest(&TestIndexes::Morton,"Test NeighborIndexes");
AddTest(&TestIndexes::MortonAll,"Test All NeighborIndexes");
AddTest(&TestIndexes::Neighbors,"Test Neighbors");
}
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment