Ejemplo n.º 1
0
/*!
    Returns true if \a ray lies on this ray; false otherwise.  If true,
    this implies that the two rays are the actually the same, but with
    different origin() points or an inverted direction().
*/
bool QRay3D::contains(const QRay3D &ray) const
{
    qreal dot = QVector3D::dotProduct(m_direction, ray.direction());
    if (!qFuzzyCompare(dot*dot, m_direction.lengthSquared() * ray.direction().lengthSquared()))
        return false;
    return contains(ray.origin());
}
Ejemplo n.º 2
0
/*!
    Finds the \a minimum_t and \a maximum_t values where \a ray intersects
    this sphere.  Returns true if intersections were found; or false if there
    is no intersection.

    If \a minimum_t and \a maximum_t are set to the same value, then \a ray
    touches the surface of the sphere at a single point.  If the t values are
    negative, then the intersection occurs before the ray's origin point
    in the reverse direction of the ray.

    The \a minimum_t and \a maximum_t values can be passed to QRay3D::point()
    to determine the actual intersection points, as shown in the following
    example:

    \code
    qreal minimum_t, maximum_t;
    if (sphere.intersection(ray, &minimum_t, &maximum_t)) {
        qDebug() << "intersections at"
                 << ray.point(minimum_t) << "and"
                 << ray.point(maximum_t);
    }
    \endcode

    \sa intersects(), QRay3D::point()
*/
bool QSphere3D::intersection(const QRay3D &ray, qreal *minimum_t, qreal *maximum_t) const
{
    QVector3D centerToOrigin = ray.origin() - m_center;
    qreal term1 = ray.direction().lengthSquared();
    qreal term2 = 2.0f * QVector3D::dotProduct(centerToOrigin, ray.direction());
    qreal term3 = centerToOrigin.lengthSquared() - m_radius * m_radius;
    qreal det = term2 * term2 - (4.0f * term1 * term3);
    if (term1 == 0.0f || det < 0.0f) {
        *minimum_t = qSNaN();
        *maximum_t = qSNaN();
        return false;
    } else if (det == 0.0f) {
        *minimum_t = *maximum_t = -term2 / (2.0f * term1);
    } else {
        qreal sqrtDet = qSqrt(det);
        qreal t1 = (-term2 - sqrtDet) / (2.0f * term1);
        qreal t2 = (-term2 + sqrtDet) / (2.0f * term1);
        if (t1 < t2) {
            *minimum_t = t1;
            *maximum_t = t2;
        } else {
            *minimum_t = t2;
            *maximum_t = t1;
        }
    }
    return true;
}
Ejemplo n.º 3
0
QDebug operator<<(QDebug dbg, const QRay3D &ray)
{
    dbg.nospace() << "QRay3D(origin("
        << ray.origin().x() << ", " << ray.origin().y() << ", "
        << ray.origin().z() << ") - direction("
        << ray.direction().x() << ", " << ray.direction().y() << ", "
        << ray.direction().z() << "))";
    return dbg.space();
}
Ejemplo n.º 4
0
/*!
    Returns the t value at which \a ray intersects this triangle, or
    not-a-number if there is no intersection.

    When the \a ray intersects this triangle, the return value is a
    parametric value that can be passed to QRay3D::point() to determine
    the actual intersection point, as shown in the following example:

    \code
    float t = triangle.intersection(ray);
    QVector3D pt;
    if (qIsNaN(t)) {
        qWarning("no intersection occurred");
    else
        pt = ray.point(t);
    \endcode

    \sa intersects(), contains(), QRay3D::point()
 */
float QTriangle3D::intersection(const QRay3D &ray) const
{
    float t = plane().intersection(ray);
    if (qIsNaN(t) || contains(ray.point(t)))
        return t;
    return qSNaN();
}
Ejemplo n.º 5
0
/*!
    Returns true if the \a ray intersects this triangle; false otherwise.

    This function will return false if the triangle is degenerate.

    \sa contains(), intersection()
*/
bool QTriangle3D::intersects(const QRay3D &ray) const
{
    float t = plane().intersection(ray);
    if (qIsNaN(t))
        return false;
    return uvInTriangle(uv(ray.point(t)));
}
Ejemplo n.º 6
0
/*!
    Returns true if the \a ray intersects this triangle; false otherwise.

    This function will return false if the triangle is degenerate.

    \sa contains(), intersection()
*/
bool QTriangle3D::intersects(const QRay3D &ray) const
{
    qreal t = plane().intersection(ray);
    if (qIsNaN(t))
        return false;
    return contains(ray.point(t));
}
Ejemplo n.º 7
0
// Test getting and setting properties via the metaobject system.
void tst_QRay3D::properties()
{
    tst_QRay3DProperties obj;

    qRegisterMetaType<QRay3D>();

    obj.setRay(QRay3D(QVector3D(1, 2, 3), QVector3D(4, 5, 6)));

    QRay3D r = qvariant_cast<QRay3D>(obj.property("ray"));
    QCOMPARE(r.origin(), QVector3D(1, 2, 3));
    QCOMPARE(r.direction(), QVector3D(4, 5, 6));

    obj.setProperty("ray",
                    qVariantFromValue
                        (QRay3D(QVector3D(-1, -2, -3), QVector3D(-4, -5, -6))));

    r = qvariant_cast<QRay3D>(obj.property("ray"));
    QCOMPARE(r.origin(), QVector3D(-1, -2, -3));
    QCOMPARE(r.direction(), QVector3D(-4, -5, -6));
}
Ejemplo n.º 8
0
QT_BEGIN_NAMESPACE

/*!
    \class QSphere3D
    \brief The QSphere3D class represents a mathematical sphere in 3D space.
    \since 4.8
    \ingroup qt3d
    \ingroup qt3d::math

    QSphere3D can be used to represent the bounding regions of objects
    in a 3D scene so that they can be easily culled if they are out of view.
    It can also be used to assist with collision testing.

    \sa QBox3D
*/

/*!
    \fn QSphere3D::QSphere3D()

    Constructs a default sphere with a center() of (0, 0, 0)
    and radius() of 1.
*/

/*!
    \fn QSphere3D::QSphere3D(const QVector3D &center, qreal radius)

    Constructs a sphere with the specified \a center and \a radius.
*/

/*!
    \fn QVector3D QSphere3D::center() const

    Returns the center of this sphere.

    \sa setCenter(), radius()
*/

/*!
    \fn void QSphere3D::setCenter(const QVector3D &center)

    Sets the \a center of this sphere.

    \sa center(), setRadius()
*/

/*!
    \fn qreal QSphere3D::radius() const

    Returns the radius of this sphere.

    \sa setRadius(), center()
*/

/*!
    \fn void QSphere3D::setRadius(qreal radius)

    Sets the \a radius of this sphere.

    \sa radius(), setCenter()
*/

/*!
    \fn bool QSphere3D::contains(const QVector3D &point) const

    Returns true if \a point is contained within the bounds of
    this sphere; false otherwise.
*/

/*!
    Returns true if this sphere intersects \a ray; false otherwise.

    \sa intersection()
*/
bool QSphere3D::intersects(const QRay3D &ray) const
{
    QVector3D centerToOrigin = ray.origin() - m_center;
    qreal term1 = ray.direction().lengthSquared();
    qreal term2 = 2.0f * QVector3D::dotProduct(centerToOrigin, ray.direction());
    qreal term3 = centerToOrigin.lengthSquared() - m_radius * m_radius;
    qreal det = term2 * term2 - (4.0f * term1 * term3);
    return term1 != 0.0f && det >= 0.0f;
}
Ejemplo n.º 9
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;
}