【问题标题】:How to properly assign indexes when transforming octree into array?将八叉树转换为数组时如何正确分配索引?
【发布时间】:2021-08-30 08:08:41
【问题描述】:

我正在尝试将八叉树展平为一个数组,以便将其传递给 GPU。我想从我的八叉树中获取数据,将其加载到 Voxel 结构的向量中,然后将其发送到 GPU。我在开始时将 2 个体素插入八叉树。这些是我的插入函数:

template<typename T>
Octree<T>::Octree(glm::vec3 position, float octreeSize, int depth) : root(position, 1.0f), depth(depth), octreeSize(octreeSize), transform(1.0f)
{
    insert(glm::vec3(0.5, 0.1, 0.7f), true);
    insert(glm::vec3(-0.5, -0.1, -0.7f), true);
    transform = glm::translate(transform, glm::vec3(0, 0, 5));
}

template<typename T>
void Octree<T>::insert(glm::vec3 pos, T data)
{
    root.subdivide(pos, data, depth, 1.0f);
}

template<typename T>
int Octree<T>::Node::getIndexOfPosition(glm::vec3 lookupPosition, glm::vec3 nodePosition) const
{
    int index = 0;
    index |= lookupPosition.y > nodePosition.y ? 4 : 0;
    index |= lookupPosition.x > nodePosition.x ? 2 : 0;
    index |= lookupPosition.z > nodePosition.z ? 1 : 0;

    return index;
}


template<typename T>
void Octree<T>::Node:: subdivide(glm::vec3 targetPos, T value, int divDepth, float parentSize)
{
    int subdivIndex = getIndexOfPosition(targetPos, position);
    if(children.empty())
    {
        for(int i = 0; i < 8; i++)
        {
            glm::vec3 newPos = position;
            float sizeModifier = parentSize * 0.5f;
            if ((i & 4) == 4)
                newPos.y += sizeModifier;
            else
                newPos.y -= sizeModifier;

            if ((i & 2) == 2)
                newPos.x += sizeModifier;
            else
                newPos.x -= sizeModifier;

            if ((i & 1) == 1)
                newPos.z += sizeModifier;
            else
                newPos.z -= sizeModifier;
            Node newNode(newPos, sizeModifier);
            children.push_back(newNode);
        }
    }

    if (divDepth > 0)
    {
        //std::cout << "Subdividing" << std::endl;
        children[subdivIndex].subdivide(targetPos, value, divDepth - 1, parentSize*0.5f);
    }
    else
    {
        children[subdivIndex].data = value;
    }
}

我的体素结构:

struct Voxel
{
    Voxel(): pIndex(-1), index(-1), pos(90000.f), col(0.f) { for (int & i : cIdx) i = -1; }
    int cIdx[8]; // The indexes of the child nodes in the vector
    int index;   // The current index of this voxel within the vector
    int pIndex;
    glm::vec4 pos;
    glm::vec4 col;
};

目前我正在预先遍历我的八叉树,我递归地遍历每个节点子节点(如果有的话),将当前体素子索引设置为当前索引,然后对其所有子节点执行相同操作。最后,一旦我们位于树的底部或没有子节点,将该节点推送到 GPU 上并将子节点的父索引设置为当前索引。这是我的功能:

template<typename T>
int
Octree<T>::Node::fillShaderVector(std::vector<Voxel> &voxelData, glm::mat4 octTransform, float octSize, int index) const
{
    Voxel voxel;
    if (isInternal())
    {
        int i = 0;
        for (auto child: children)
        {
            // I think this is where we have issues
            voxel.cIdx[i] = index;
            index = child.fillShaderVector(voxelData, octTransform, octSize, index);
            i++;
        }
    }

    voxel.pos = glm::vec4(position, 1.0);
    // Store size as the 4th element in the vector
    voxel.pos.w = voxelSize;
    voxel.col = glm::vec4(1.0);
    voxel.index = index;

    voxelData.push_back(voxel);
    index++;

    if (isInternal())
    {
        for(int i : voxel.cIdx)
            voxelData[i].pIndex = voxel.index;
    }

    return index;
}

template<typename T>
bool Octree<T>::Node::isInternal() const
{
    return !children.empty();
}

这会正确地遍历节点,并且我能够为每个体素获取正确的索引,但是我似乎无法正确设置父索引。

示例输出(为简洁起见,我删掉了很多,它从 0..56 Parent: -1 表示没有父节点,即应该只是根节点,而 child: -1,表示它是一个叶节点):

Index: 0
Parent: 56
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 1
Parent: 24
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 2
Parent: 24
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 3
Parent: 24
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 4
Parent: 24
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 5
Parent: 20
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 6
Parent: 20
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 7
Parent: 20
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 8
Parent: 20
Children: -1 -1 -1 -1 -1 -1 -1 -1
...
Index: 16
Parent: 19
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 17
Parent: 19
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 18
Parent: 19
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 19
Parent: -1
Children: 11 12 13 14 15 16 17 18
Index: 20
Parent: -1
Children: 4 5 6 7 8 9 10 11
...
Index: 47
Parent: 48
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 48
Parent: -1
Children: 32 33 34 43 44 45 46 47
Index: 49
Parent: 55
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 50
Parent: 55
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 51
Parent: 55
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 52
Parent: 55
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 53
Parent: 55
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 54
Parent: 55
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 55
Parent: -1
Children: 31 32 49 50 51 52 53 54
Index: 56
Parent: -1
Children: 0 25 26 27 28 29 30 31

我在 fillShaderVector 函数中做错了什么,导致我无法准确填写父索引?

【问题讨论】:

  • 您是否尝试调试过代码?
  • 是的。经过数小时的失败后,我求助于堆栈溢出。

标签: c++ arrays tree tree-traversal octree


【解决方案1】:

我解决了这个问题,在预购中我将体素推送到向量上,然后使用它的索引直接对向量进行修改并成功更新父数据和子数据。

新的插入代码

template<typename T>
int
Octree<T>::Node::fillShaderVector(std::vector<Voxel> &voxelData, glm::mat4 octTransform, float octSize, int index) const
{
    Voxel voxel;

    voxel.pos = glm::vec4(position, 1.0);
    // Store size as the 4th element in the vector
    voxel.pos.w = voxelSize;
    voxel.col = glm::vec4(1.0);
    voxel.index = index;

    voxelData.push_back(voxel);
    index++;
    if (isInternal())
    {
        int i = 0;
        for (auto child: children)
        {
            voxelData[voxel.index].cIdx[i] = index;
            index = child.fillShaderVector(voxelData, octTransform, octSize, index);
            i++;
        }
    }
    if (isInternal())
    {
        for(auto c: voxelData[voxel.index].cIdx)
            if(c != -1) voxelData[c].pIndex = voxel.index;
    }

    return index;
}

这会导致正确的索引和层次结构

Index: 0
Parent: -1
Children: 1 26 27 28 29 30 31 32
Index: 1
Parent: 0
Children: 2 3 4 5 6 23 24 25
Index: 2
Parent: 1
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 3
Parent: 1
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 4
Parent: 1
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 5
Parent: 1
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 6
Parent: 1
Children: 7 8 9 10 11 12 13 14
Index: 7
Parent: 6
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 8
Parent: 6
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 9
Parent: 6
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 10
Parent: 6
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 11
Parent: 6
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 12
Parent: 6
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 13
Parent: 6
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 14
Parent: 6
Children: 15 16 17 18 19 20 21 22
Index: 15
Parent: 14
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 16
Parent: 14
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 17
Parent: 14
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 18
Parent: 14
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 19
Parent: 14
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 20
Parent: 14
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 21
Parent: 14
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 22
Parent: 14
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 23
Parent: 1
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 24
Parent: 1
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 25
Parent: 1
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 26
Parent: 0
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 27
Parent: 0
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 28
Parent: 0
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 29
Parent: 0
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 30
Parent: 0
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 31
Parent: 0
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 32
Parent: 0
Children: 33 34 51 52 53 54 55 56
Index: 33
Parent: 32
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 34
Parent: 32
Children: 35 36 37 46 47 48 49 50
Index: 35
Parent: 34
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 36
Parent: 34
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 37
Parent: 34
Children: 38 39 40 41 42 43 44 45
Index: 38
Parent: 37
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 39
Parent: 37
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 40
Parent: 37
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 41
Parent: 37
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 42
Parent: 37
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 43
Parent: 37
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 44
Parent: 37
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 45
Parent: 37
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 46
Parent: 34
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 47
Parent: 34
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 48
Parent: 34
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 49
Parent: 34
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 50
Parent: 34
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 51
Parent: 32
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 52
Parent: 32
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 53
Parent: 32
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 54
Parent: 32
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 55
Parent: 32
Children: -1 -1 -1 -1 -1 -1 -1 -1
Index: 56
Parent: 32
Children: -1 -1 -1 -1 -1 -1 -1 -1

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-29
    • 1970-01-01
    相关资源
    最近更新 更多