Ejemplo n.º 1
0
_Use_decl_annotations_
int32_t BspCompiler::ProcessTriangles(Triangle** triangles, uint32_t count)
{
    Triangle* front = nullptr;
    Triangle* back = nullptr;
    const Triangle* splitTriangle = nullptr;
    uint32_t frontCount, backCount;

    if (FindBestSplit(triangles, count, &splitTriangle, &front, &frontCount, &back, &backCount))
    {
        // Able to split the set of triangles. We need a node to desribe this
        Node node;
        node.Plane = splitTriangle->Plane;
        node.Front = ProcessTriangles(&front, frontCount);
        node.Back = ProcessTriangles(&back, backCount);
        _nodes.push_back(node);
        return static_cast<int32_t>(_nodes.size() - 1);
    }
    else
    {
        // Not able to split, already convex. Make it a sector
        Sector sector;
        CreateSectorFromTriangles(triangles, count, &sector);
        _sectors.push_back(sector);
        return static_cast<int32_t>(_sectors.size() - 1) * -1 - 1;
    }
}
IntpQdrNonuniform2<Real>::IntpQdrNonuniform2 (const Delaunay2<Real>& DT,
    Real* F, bool owner)
    :
    mDT(&DT),
    mF(F),
    mFOwner(owner),
    mFXFYOwner(true)
{
    EstimateDerivatives();
    ProcessTriangles();
}
IntpQdrNonuniform2<Real>::IntpQdrNonuniform2 (const Delaunay2<Real>& DT,
    Real* F, Real* FX, Real* FY, bool owner)
    :
    mDT(&DT),
    mF(F),
    mFX(FX),
    mFY(FY),
    mFOwner(owner),
    mFXFYOwner(owner)
{
    ProcessTriangles();
}
Ejemplo n.º 4
0
_Use_decl_annotations_
uint32_t BIH::ProcessTriangles(CompileTriangle** triangles, uint32_t count, const AABB& bounds)
{
    assert(*triangles != nullptr);
    assert(count > 0);

    if (count < 4)
    {
        // Make a leaf
        Node node;
        node.Axis = 3;

        node.StartTriangle = (uint32_t)_triangles.size();
        CompileTriangle* t = *triangles;
        while (t != nullptr)
        {
            CompileTriangle* next = t->Next;
            _triangles.push_back(Triangle(t));
            delete t;
            t = next;
        }
        *triangles = nullptr;

        node.NumTriangles = (uint32_t)_triangles.size() - node.StartTriangle;

        _nodes.push_back(node);
        return (uint32_t)_nodes.size() - 1;
    }
    else
    {
        // Split

        // Choose longest axis as initial candidate, but we may end up
        // trying all three if we can't find a good one
        uint8_t axis = 0;
        float xLength = bounds.GetMax().x - bounds.GetMin().x;
        float yLength = bounds.GetMax().y - bounds.GetMin().y;
        float zLength = bounds.GetMax().z - bounds.GetMin().z;
        if (yLength > xLength)
        {
            axis = 1;
            if (zLength > yLength)
            {
                axis = 2;
            }
        }
        else if (zLength > xLength)
        {
            axis = 2;
        }

        uint8_t startAxis = axis;

        CompileTriangle* t;
        uint32_t minCount;
        uint32_t maxCount;

        // Loop and test each axis. Doesn't actually modify lists yet, just counting
        for (;;)
        {
            t = *triangles;

            float totalAlongAxis = 0;
            while (t != nullptr)
            {
                totalAlongAxis += *(&t->Centroid.x + axis);
                t = t->Next;
            }

            float averageAlongAxis = totalAlongAxis / (float)count;

            t = *triangles;
            minCount = 0;
            maxCount = 0;

            while (t != nullptr)
            {
                float v = *(&t->Centroid.x + axis);
                if (v < averageAlongAxis)
                {
                    ++minCount;
                }
                else
                {
                    ++maxCount;
                }

                t = t->Next;
            }

            if (minCount == 0 || maxCount == 0)
            {
                // try the next axis if this one wasn't any good
                axis = (axis + 1) % 3;
                if (axis == startAxis)
                {
                    // bail, no good
                    break;
                }
            }
            else
            {
                // this axis is fine.
                break;
            }
        };

        if (minCount == 0 || maxCount == 0)
        {
            // Failed to split, just make it a leaf
            Node node;
            node.Axis = 3;

            node.StartTriangle = (uint32_t)_triangles.size();
            CompileTriangle* t = *triangles;
            while (t != nullptr)
            {
                CompileTriangle* next = t->Next;
                _triangles.push_back(Triangle(t));
                delete t;
                t = next;
            }
            *triangles = nullptr;

            node.NumTriangles = (uint32_t)_triangles.size() - node.StartTriangle;

            _nodes.push_back(node);
            return (uint32_t)_nodes.size() - 1;
        }
        else
        {
            // Now we need to actually build lists
            CompileTriangle* minTriangles = nullptr;
            CompileTriangle* maxTriangles = nullptr;
            float min = FLT_MAX;
            float max = -FLT_MAX;

            minCount = 0;
            maxCount = 0;

            t = *triangles;

            float totalAlongAxis = 0;
            while (t != nullptr)
            {
                totalAlongAxis += *(&t->Centroid.x + axis);
                t = t->Next;
            }

            float averageAlongAxis = totalAlongAxis / (float)count;

            t = *triangles;
            while (t != nullptr)
            {
                CompileTriangle* next = t->Next;

                float v = *(&t->Centroid.x + axis);
                if (v < averageAlongAxis)
                {
                    max = std::max(max, *(&t->Max.x + axis));
                    PUSH(&minTriangles, t);
                    ++minCount;
                }
                else
                {
                    min = std::min(min, *(&t->Min.x + axis));
                    PUSH(&maxTriangles, t);
                    ++maxCount;
                }

                t = next;
            }

            Node node;
            node.Axis = axis;
            node.Max = max;
            node.Min = min;

            _nodes.push_back(node);

            uint32_t index = (uint32_t)_nodes.size() - 1;

            XMFLOAT3 boundsSide = bounds.GetMax();
            *(&boundsSide.x + axis) = max;
            uint32_t minNode = ProcessTriangles(&minTriangles, minCount, AABB(bounds.GetMin(), boundsSide));
            DBG_UNREFERENCED_LOCAL_VARIABLE(minNode);
            assert(minNode == index + 1);

            boundsSide = bounds.GetMin();
            *(&boundsSide.x + axis) = min;
            _nodes[index].MaxNode = ProcessTriangles(&maxTriangles, maxCount, AABB(boundsSide, bounds.GetMax()));

            return index;
        }
    }
}