Commit 62b05926 authored by David Flynn's avatar David Flynn
Browse files

geom/m44752: false occupancy aware neighbour determination

The neighbour pattern for a node indicates occupied neighbouring nodes.

This commit updates the definition of occupancy for the (x-1), (y-1),
and (z-1) neighbours to be occupied if the neighbour's adjoining
children (ie sharing a face with the current node) are occupied.

In the 1-D figure below, at a depth d, the node 'X' has two occupied
neighbours 'R' and 'L'.  When determining the neighbour pattern of X,
the (x-1) state of the neighbour's adjoining child ('r') is used
instead.  For completeness, nodes marked with '?' are not causally
available.

  d+0:   R|X|L
  d+1:  Rr|??|??
parent f777b6ab
......@@ -76,6 +76,54 @@ updateGeometryOccupancyAtlas(
//----------------------------------------------------------------------------
void
updateGeometryOccupancyAtlasOccChild(
const PCCVector3<uint32_t>& pos,
int nodeSizeLog2,
uint8_t childOccupancy,
MortonMap3D* occupancyAtlas)
{
uint32_t mask = (1 << occupancyAtlas->cubeSizeLog2()) - 1;
uint32_t x = (pos[0] >> nodeSizeLog2) & mask;
uint32_t y = (pos[1] >> nodeSizeLog2) & mask;
uint32_t z = (pos[2] >> nodeSizeLog2) & mask;
occupancyAtlas->setChildOcc(x, y, z, childOccupancy);
}
//----------------------------------------------------------------------------
// neighIdx: 0 => (x-1), 1 => (y-1), 2 => (z-1)
//
static uint32_t
updatePatternFromNeighOccupancy(
const MortonMap3D& occupancyAtlas,
int x,
int y,
int z,
uint32_t neighPattern,
int neighIdx)
{
static const uint8_t childMasks[] = {
0xf0 /* x-1 */, 0xcc /* y-1 */, 0xaa /* z-1 */
};
uint32_t patternBit = 1 << (1 << neighIdx);
uint8_t childMask = childMasks[neighIdx];
if (neighPattern & patternBit) {
uint8_t child_occ = occupancyAtlas.getChildOcc(x, y, z);
child_occ &= childMask;
if (!child_occ) {
/* neighbour is falsely occupied */
neighPattern ^= patternBit;
}
}
return neighPattern;
}
//----------------------------------------------------------------------------
uint32_t
makeGeometryNeighPattern(
const PCCVector3<uint32_t>& position,
......@@ -105,6 +153,24 @@ makeGeometryNeighPattern(
neighPattern |= occupancyAtlas.getWithCheck(x, y, z - 1) << 4;
neighPattern |= occupancyAtlas.getWithCheck(x, y, z + 1) << 5;
}
// Above, the neighbour pattern corresponds directly to the six same
// sized neighbours of the given node.
// The patten is then refined by examining the available children
// of the same neighbours.
if (x > 0)
neighPattern = updatePatternFromNeighOccupancy(
occupancyAtlas, x - 1, y, z, neighPattern, 0);
if (y > 0)
neighPattern = updatePatternFromNeighOccupancy(
occupancyAtlas, x, y - 1, z, neighPattern, 1);
if (z > 0)
neighPattern = updatePatternFromNeighOccupancy(
occupancyAtlas, x, y, z - 1, neighPattern, 2);
return neighPattern;
}
......
......@@ -64,6 +64,7 @@ public:
_cubeSize = 1 << cubeSizeLog2;
_bufferSizeInBytes = 1 << (3 * halfCubeSizeLog2);
_buffer.reset(new uint8_t[_bufferSizeInBytes]);
_childOccupancy.reset(new uint8_t[_bufferSizeInBytes << 3]);
_updates.reserve(1 << 16);
}
......@@ -116,6 +117,18 @@ public:
return get(x, y, z);
}
void setChildOcc(int32_t x, int32_t y, int32_t z, uint8_t childOccupancy)
{
_childOccupancy[getByteIndex(x << 1, y << 1, z << 1)] = childOccupancy;
}
uint8_t getChildOcc(int32_t x, int32_t y, int32_t z) const
{
uint8_t childOccupancy =
_childOccupancy[getByteIndex(x << 1, y << 1, z << 1)];
return childOccupancy;
}
private:
int32_t getBitIndex(const int32_t x, const int32_t y, const int32_t z) const
{
......@@ -137,6 +150,9 @@ private:
// A list of indexes in _buffer that are dirty
std::vector<uint32_t> _updates;
// Child occupancy values
std::unique_ptr<uint8_t[]> _childOccupancy;
};
//============================================================================
......@@ -158,4 +174,10 @@ void updateGeometryOccupancyAtlas(
MortonMap3D* occupancyAtlas,
PCCVector3<uint32_t>* atlasOrigin);
void updateGeometryOccupancyAtlasOccChild(
const PCCVector3<uint32_t>& pos,
int nodeSizeLog2,
uint8_t childOccupancy,
MortonMap3D* occupancyAtlas);
} // namespace pcc
......@@ -422,6 +422,10 @@ decodeGeometryOctree(
assert(occupancy > 0);
// update atlas for advanced neighbours
updateGeometryOccupancyAtlasOccChild(
node0.pos, nodeSizeLog2, occupancy, &occupancyAtlas);
// population count of occupancy for IDCM
int numOccupied = popcnt(occupancy);
......
......@@ -454,6 +454,10 @@ encodeGeometryOctree(
&occupancyPrediction);
}
// update atlas for advanced neighbours
updateGeometryOccupancyAtlasOccChild(
node0.pos, nodeSizeLog2, occupancy, &occupancyAtlas);
// encode child occupancy map
assert(occupancy > 0);
encoder.encodeOccupancy(
......
Supports Markdown
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