Esempio n. 1
0
static void kdSerialize(u::vector<unsigned char> &buffer, const T *data, size_t size) {
    const unsigned char *const beg = (const unsigned char *const)data;
    const unsigned char *const end = ((const unsigned char *const)data) + size;
    buffer.insert(buffer.end(), beg, end);
}
Esempio n. 2
0
kdNode::kdNode(kdTree *tree, const u::vector<int> &tris, size_t recursionDepth)
    : m_front(nullptr)
    , m_back(nullptr)
    , m_sphereRadius(0.0f)
{
    const size_t triangleCount = tris.size();

    if (recursionDepth > tree->m_depth)
        tree->m_depth = recursionDepth;
    if (recursionDepth > kdTree::kMaxRecursionDepth)
        return;

    tree->m_nodeCount++;

    if (!calculateSphere(tree, tris)) {
        u::Log::err("[world] => level geometry is too large: collision detection and rendering may not work");
        return;
    }

    u::vector<int> fx, fy, fz; // front
    u::vector<int> bx, by, bz; // back
    u::vector<int> sx, sy, sz; // split
    u::vector<int> *const frontList[3] = { &fx, &fy, &fz };
    u::vector<int> *const backList[3] = { &bx, &by, &bz };
    u::vector<int> *const splitList[3] = { &sx, &sy, &sz };

    m::plane plane[3];
    float ratio[3];
    size_t best = recursionDepth % 3;

    // find a plane which gives a good balanced node
    for (size_t i = 0; i < 3; i++) {
        split(tree, tris, m::axis(i), *frontList[i], *backList[i], *splitList[i], plane[i]);
        const size_t fsize = (*frontList[i]).size();
        const size_t bsize = (*backList[i]).size();
        if (fsize > bsize)
            ratio[i] = (float)bsize / (float)fsize;
        else
            ratio[i] = (float)fsize / (float)bsize;
    }

    float bestRatio = 0.0f;
    for (size_t i = 0; i < 3; i++) {
        if (ratio[i] > bestRatio) {
            best = i;
            bestRatio = ratio[i];
        }
    }

    m_splitPlane = plane[best];

    // when there isn't many triangles left, create a leaf. In doing so we can
    // continue to create further subdivisions.
    if (frontList[best]->size() == 0 || backList[best]->size() == 0 || triangleCount <= kdTree::kMaxTrianglesPerLeaf) {
        // create subspace with `triangleCount` polygons
        m_triangles.insert(m_triangles.begin(), tris.begin(), tris.end());
        tree->m_leafCount++;
        return;
    }

    // insert the split triangles on both sides of the plane.
    frontList[best]->insert(frontList[best]->end(), splitList[best]->begin(), splitList[best]->end());
    backList[best]->insert(backList[best]->end(), splitList[best]->begin(), splitList[best]->end());

    // recurse
    m_front = new kdNode(tree, *frontList[best], recursionDepth + 1);
    m_back = new kdNode(tree, *backList[best], recursionDepth + 1);
}