この問題に遭遇したとき、nVidia (「効率的なスパース ボクセル オクトリー」)の人々がボクセルのことを行っていたように、スパース オクトリーの実装を作成するのに苦労していました。
octree のリーフがどこにあるかを示す byte 型 (8 ビットのみ) のビットフィールドがあります (1 はリーフを意味し、0 はリーフがないことを意味し、8 つのノードが接続されている --> 8 ビット)。私が今やりたいことは、葉の位置の配列を返すことです。私の現在の実装では、while ループを使用して、LSB が設定されているかどうかを確認しています。入力はその後 1 シフトされます。だからここに私がそれを行う方法があります:
int leafposition = _leafmask & _validmask;
int[] result = new int[8];
int arrayPosition = 0;
int iteration = 0;
while ( leafposition > 0 )
{
iteration++; //nodes are not zero-indexed ... ?
if ( (leafposition & 1) == 1 ) // LSB set?
{
result.SetValue( iteration, arrayPosition );
arrayPosition++;
};
leafposition = leafposition >> 1;
}
return result;
これは見栄えがよくなく、気になる点が 2 つあります。
- この while ループは for ループを模倣しています
- 結果の配列は 8 つの値よりも小さくなる可能性が高いですが、サイズ変更にはコストがかかります
結果[2,4,6]
は 42 のようになると思い(0010 1010)
ます。
まだ読みやすい、よりエレガントなソリューションを提供できる人はいますか?
結果
以前に実装した octree リーフ カウントの関数を使用して、配列を適切なサイズに設定しています。