Given eight integers, what is the fastest way to check if they are all the same or not?
Maybe, some clever bit manipulation?
(This is used in a voxel engine - integers are material IDs: if a cell has different material IDs at corners, then it must intersect a surface.)
I've implemented this simple solution, but it only works with 8-bit values, and 255 materials (0 == empty air) won't be enough:
/// returns true if all eight bytes are equal to each other
template< typename T >
bool AreAllTheSame8( const T (&_array)[8] )
{
const T v0 = _array[ 0 ];
const T v1 = _array[ 1 ];
const T v2 = _array[ 2 ];
const T v3 = _array[ 3 ];
const T v4 = _array[ 4 ];
const T v5 = _array[ 5 ];
const T v6 = _array[ 6 ];
const T v7 = _array[ 7 ];
static_assert(sizeof(T) == sizeof(uint8_t));
uint8_t counts[256];
mxZERO_OUT(counts);
counts[ v0 ]++;
counts[ v1 ]++;
counts[ v2 ]++;
counts[ v3 ]++;
counts[ v4 ]++;
counts[ v5 ]++;
counts[ v6 ]++;
counts[ v7 ]++;
return counts[ v0 ] == 8;
}
In reality, the zero materials are not 'counted' (i can explain why if you're curious), and the above solution results in this ugly and inefficient code:
/// returns true if all eight materials are equal to each other
bool IsCellHomogeneous( const MaterialID (&_voxels)[8] )
{
const MaterialID v0 = _voxels[ 0 ];
const MaterialID v1 = _voxels[ 1 ];
const MaterialID v2 = _voxels[ 2 ];
const MaterialID v3 = _voxels[ 3 ];
const MaterialID v4 = _voxels[ 4 ];
const MaterialID v5 = _voxels[ 5 ];
const MaterialID v6 = _voxels[ 6 ];
const MaterialID v7 = _voxels[ 7 ];
U8 counts[256];
mxZERO_OUT(counts);
UINT numSolidMaterials = 0;
UINT lastSolidMaterial = 0;
// zero material IDs correspond to empty space/air
if( v0 ) {
counts[ v0 ]++;
numSolidMaterials++;
lastSolidMaterial = v0;
}
if( v1 ) {
counts[ v1 ]++;
numSolidMaterials++;
lastSolidMaterial = v1;
}
if( v2 ) {
counts[ v2 ]++;
numSolidMaterials++;
lastSolidMaterial = v2;
}
if( v3 ) {
counts[ v3 ]++;
numSolidMaterials++;
lastSolidMaterial = v3;
}
if( v4 ) {
counts[ v4 ]++;
numSolidMaterials++;
lastSolidMaterial = v4;
}
if( v5 ) {
counts[ v5 ]++;
numSolidMaterials++;
lastSolidMaterial = v5;
}
if( v6 ) {
counts[ v6 ]++;
numSolidMaterials++;
lastSolidMaterial = v6;
}
if( v7 ) {
counts[ v7 ]++;
numSolidMaterials++;
lastSolidMaterial = v7;
}
return counts[ lastSolidMaterial ] == numSolidMaterials;
}