c++ - 用于存储 3D float 位置的莫顿代码

标签 c++ data-structures octree

我正在尝试实现本文中解释的内容: http://devblogs.nvidia.com/parallelforall/thinking-parallel-part-iii-tree-construction-gpu/

// Expands a 10-bit integer into 30 bits
// by inserting 2 zeros after each bit.
unsigned int expandBits(unsigned int v)
{
    v = (v * 0x00010001u) & 0xFF0000FFu;
    v = (v * 0x00000101u) & 0x0F00F00Fu;
    v = (v * 0x00000011u) & 0xC30C30C3u;
    v = (v * 0x00000005u) & 0x49249249u;
    return v;
}

// Calculates a 30-bit Morton code for the
// given 3D point located within the unit cube [0,1].
unsigned int morton3D(float x, float y, float z)
{
    x = min(max(x * 1024.0f, 0.0f), 1023.0f);
    y = min(max(y * 1024.0f, 0.0f), 1023.0f);
    z = min(max(z * 1024.0f, 0.0f), 1023.0f);
    unsigned int xx = expandBits((unsigned int)x);
    unsigned int yy = expandBits((unsigned int)y);
    unsigned int zz = expandBits((unsigned int)z);
    return xx * 4 + yy * 2 + zz;
}

当我使用提供的示例尝试 Morton3D 函数时, (0.1010, 0.0111, 0.1100) 它返回 1479990 而不是 101011110010。

我是否遗漏了此处未解释的内容?

谢谢! -D

最佳答案

您遗漏了两个要点:

  1. 文章中给出的样本数(0.1010、0.0111、0.1100)实际上是用二进制写的。这意味着 0.1010 实际上是 0.5+0.125=0.6250.0111 是 0.25+0.125+0.0625=0.4375 并且0.1100 是 0.5+0.25=0.75。把这些放进去,你就会看到。

  2. 示例图的每个分量仅使用 4 位,在 Morton 编码中总共使用 12 位,而实际代码每个分量使用 10 位,总共 30 位。因此,在您得到的结果中,忽略结果的前 2 位,并查看其余位,看看您是否能算出来。

顺便说一句,文章中的代码是正确的,并且按照它所说的去做。

关于c++ - 用于存储 3D float 位置的莫顿代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31363379/

相关文章:

c++ - std::move 和 std::forward 有什么区别

c++ - 在 C++ 中寻找解决此问题的特定设计模式

algorithm - 回溯尾递归算法可以转换为迭代吗?

opengl - 大型 3D 场景流

c++ - c++中如何避免内存溢出引起的错误信息

c++ - 对 STL 容器的安全并行只读访问

algorithm - 计算具有更新的段中的反转

c++ - C++ 中的四叉树或八叉树模板化实现

python - 从常规网格数据库创建波前 .obj 文件

c++ - Windows API "Chess Timer"Sepmaphore 事件