Mentions légales du service

Skip to content
Snippets Groups Projects
Commit 0f084a95 authored by BRAMAS Berenger's avatar BRAMAS Berenger
Browse files

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

parent 8c299582
No related branches found
No related tags found
No related merge requests found
......@@ -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");
}
};
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment