Esempio n. 1
0
    void recursiveBuild(uint32_t nodeIndex, uint32_t start, uint32_t end, uint32_t* indices,
                        PositionFunctor getPosition, uint32_t& nextFreeNode) {
        if(start + 1 == end) {
            // One node to process, it's a  leaf
            m_Nodes[nodeIndex].setAsLeaf();

            m_NodesData[nodeIndex].m_nIndex = indices[start];
            m_NodesData[nodeIndex].m_Position = getPosition(indices[start]);

            return;
        }

        // Compute the bounding box of the data
        BBox3f bound;
        for(uint32_t i = start; i != end; ++i) {
            bound += getPosition(indices[i]);
        }
        // The split axis is the one with maximal extent for the data
        uint32_t splitAxis = maxComponent(abs(bound.size()));
        uint32_t splitIndex = (start + end) / 2;
        // Reorganize the pointers such that the middle element is the middle element on the split axis
        std::nth_element(indices + start, indices + splitIndex, indices + end,
                         [splitAxis, &getPosition](uint32_t lhs, uint32_t rhs) -> bool {
                            float v1 = getPosition(lhs)[splitAxis];
                            float v2 = getPosition(rhs)[splitAxis];
                            return v1 == v2 ? lhs < rhs : v1 < v2;
                         });
        float splitPosition = getPosition(indices[splitIndex])[splitAxis];
        m_Nodes[nodeIndex].setAsInnerNode(splitPosition, splitAxis);
        m_NodesData[nodeIndex].m_nIndex = indices[splitIndex];
        m_NodesData[nodeIndex].m_Position = getPosition(indices[splitIndex]);

        // Build the left subtree
        if(start < splitIndex) {
            m_Nodes[nodeIndex].m_bHasLeftChild = true;
            uint32_t childIndex = nextFreeNode++;
            recursiveBuild(childIndex, start, splitIndex, indices, getPosition, nextFreeNode);
        }

        // Build the right subtree
        if(splitIndex + 1 < end) {
            m_Nodes[nodeIndex].m_nRightChildIndex = nextFreeNode++;
            recursiveBuild(m_Nodes[nodeIndex].m_nRightChildIndex, splitIndex + 1, end, indices, getPosition, nextFreeNode);
        }
    }
void GLVoxelizerTripiana2009::initGLState(uint32_t resolution, BBox3f bbox,
                                          GLVoxelFramebuffer& framebuffer, Mat4f& gridToWorldMatrix) {
    auto v = bbox.upper - bbox.lower;

    auto bboxCenter = 0.5f * (bbox.lower + bbox.upper);
    // Grow of 5% the size of the bounding box to ensure that we don't miss any triangle that are at the edge
    bbox.lower = bboxCenter - 0.55f * v;
    bbox.upper = bboxCenter + 0.55f * v;

    auto m_res = resolution;
    // Requiered number of color buffer
    auto m_numRenderTargets = ceil((double)m_res / 128.0);

    auto bboxSize = bbox.size();
    auto m_AABCLength = reduceMax(bboxSize);

    auto m_voxelLength = m_AABCLength / (float)m_res;


    auto m_origBBox = bboxCenter - glm::vec3(0.5f * m_AABCLength);

    gridToWorldMatrix = scale(translate(Mat4f(1.f), m_origBBox), glm::vec3(m_voxelLength));

    // Use the shaders
    m_Program.use();

    // Desactivate depth, cullface
    glDisable(GL_DEPTH_TEST);
    glDisable(GL_CULL_FACE);

    // Blending activated
    glEnable(GL_COLOR_LOGIC_OP);
    glLogicOp(GL_OR);

    // Init FrameBuffer
    if (!framebuffer.init(m_res, m_res, m_res, m_numRenderTargets)){
        std::cerr << "FBO Error" << std::endl;
    }

    //Projection matrix : Adapt the viewport to the size of the mesh
    glm::mat4 P = glm::ortho(-m_AABCLength * 0.5f,
        m_AABCLength * 0.5f,
        -m_AABCLength * 0.5f,
        m_AABCLength * 0.5f,
        0.f,
        m_AABCLength);

    glm::vec3 position(bboxCenter.x, bboxCenter.y, bboxCenter.z + 0.5 * m_AABCLength);
    glm::vec3 point(bboxCenter.x, bboxCenter.y, bboxCenter.z);
    glm::mat4 V = glm::lookAt(position, point, glm::vec3(0, 1, 0));

    // Get the MVP Matrix
    glm::mat4 MVPMatrix = P * V;

    // Set uniforms
    MVP.set(MVPMatrix);
    halfPixelSize.set(Vec2f(1.f / m_res));
    numVoxels.set(resolution);
    origBBox.set(m_origBBox);
    numRenderTargets.set(m_numRenderTargets);
    voxelSize.set(m_voxelLength);

    framebuffer.bind(GL_DRAW_FRAMEBUFFER);

    // Set the list of draw buffers.
    std::vector<GLenum> DrawBuffers(m_numRenderTargets, 0);
    for (int i = 0; i < m_numRenderTargets; ++i){
        DrawBuffers[i] = GL_COLOR_ATTACHMENT0 + i;
    }
    glDrawBuffers(m_numRenderTargets, DrawBuffers.data());

    glViewport(0, 0, m_res, m_res);

    // Clear the window
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}