コード例 #1
0
qreal QGLBezierPatch::intersection
    (qreal result, int depth, const QRay3D& ray, bool anyIntersection,
     qreal xtex, qreal ytex, qreal wtex, qreal htex, QVector2D *tc)
{
    // Check the convex hull of the patch for an intersection.
    // If no intersection with the convex hull, then there is
    // no point subdividing this patch further.
    QBox3D box;
    for (int point = 0; point < 16; ++point)
        box.unite(points[point]);
    if (!box.intersects(ray))
        return result;

    // Are we at the lowest point of subdivision yet?
    if (depth <= 1) {
        // Divide the patch into two triangles and intersect with those.
        QTriangle3D triangle1(points[0], points[3], points[12]);
        qreal t = triangle1.intersection(ray);
        if (!qIsNaN(t)) {
            result = combineResults(result, t);
            if (result == t) {
                QVector2D uv = triangle1.uv(ray.point(t));
                QVector2D tp(xtex, ytex);
                QVector2D tq(xtex + wtex, ytex);
                QVector2D tr(xtex, ytex + htex);
                *tc = uv.x() * tp + uv.y() * tq + (1 - uv.x() - uv.y()) * tr;
            }
        } else {
            QTriangle3D triangle2(points[3], points[15], points[12]);
            qreal t = triangle2.intersection(ray);
            if (!qIsNaN(t)) {
                result = combineResults(result, t);
                if (result == t) {
                    QVector2D uv = triangle2.uv(ray.point(t));
                    QVector2D tp(xtex + wtex, ytex);
                    QVector2D tq(xtex + wtex, ytex + htex);
                    QVector2D tr(xtex, ytex + htex);
                    *tc = uv.x() * tp + uv.y() * tq + (1 - uv.x() - uv.y()) * tr;
                }
            }
        }
    } else {
        // Subdivide the patch to find the point of intersection.
        QGLBezierPatch patch1, patch2, patch3, patch4;
        subDivide(patch1, patch2, patch3, patch4);
        --depth;
        qreal hwtex = wtex / 2.0f;
        qreal hhtex = htex / 2.0f;
        result = patch1.intersection
            (result, depth, ray, anyIntersection,
             xtex, ytex, hwtex, hhtex, tc);
        if (anyIntersection && !qIsNaN(result))
            return result;
        result = patch2.intersection
            (result, depth, ray, anyIntersection,
             xtex + hwtex, ytex, hwtex, hhtex, tc);
        if (anyIntersection && !qIsNaN(result))
            return result;
        result = patch3.intersection
            (result, depth, ray, anyIntersection,
             xtex, ytex + hhtex, hwtex, hhtex, tc);
        if (anyIntersection && !qIsNaN(result))
            return result;
        result = patch4.intersection
            (result, depth, ray, anyIntersection,
             xtex + hwtex, ytex + hhtex, hwtex, hhtex, tc);
    }
    return result;
}