21 #include <Qt3DRender/QCamera>    26 namespace QgsRayCastingUtils
    34     : m_direction( 0.0f, 0.0f, 1.0f )
    38   Ray3D::Ray3D( QVector3D origin, QVector3D direction, 
float distance )
    40     , m_direction( direction )
    41     , m_distance( distance )
    44   QVector3D Ray3D::origin()
 const    49   void Ray3D::setOrigin( QVector3D value )
    54   QVector3D Ray3D::direction()
 const    59   void Ray3D::setDirection( QVector3D value )
    67   float Ray3D::distance()
 const    72   void Ray3D::setDistance( 
float distance )
    74     m_distance = distance;
    77   QVector3D Ray3D::point( 
float t )
 const    79     return m_origin + t * m_direction;
    82   Ray3D &Ray3D::transform( 
const QMatrix4x4 &matrix )
    84     m_origin = matrix * m_origin;
    85     m_direction = matrix.mapVector( m_direction );
    90   Ray3D Ray3D::transformed( 
const QMatrix4x4 &matrix )
 const    92     return Ray3D( matrix * m_origin, matrix.mapVector( m_direction ) );
    97     return m_origin == other.origin() && m_direction == other.direction();
   102     return !( *
this == other );
   105   bool Ray3D::contains( QVector3D point )
 const   107     QVector3D ppVec( point - m_origin );
   108     if ( ppVec.isNull() ) 
   110     const float dot = QVector3D::dotProduct( ppVec, m_direction );
   111     if ( qFuzzyIsNull( dot ) )
   113     return qFuzzyCompare( dot * dot, ppVec.lengthSquared() * m_direction.lengthSquared() );
   116   bool Ray3D::contains( 
const Ray3D &ray )
 const   118     const float dot = QVector3D::dotProduct( m_direction, ray.direction() );
   119     if ( !qFuzzyCompare( dot * dot, m_direction.lengthSquared() * ray.direction().lengthSquared() ) )
   121     return contains( ray.origin() );
   124   float Ray3D::projectedDistance( QVector3D point )
 const   126     Q_ASSERT( !m_direction.isNull() );
   128     return QVector3D::dotProduct( point - m_origin, m_direction ) /
   129            m_direction.lengthSquared();
   132   QVector3D Ray3D::project( QVector3D vector )
 const   134     QVector3D norm = m_direction.normalized();
   135     return QVector3D::dotProduct( vector, norm ) * norm;
   139   float Ray3D::distance( QVector3D point )
 const   141     float t = projectedDistance( point );
   142     return ( point - ( m_origin + t * m_direction ) ).length();
   145   QDebug 
operator<<( QDebug dbg, 
const Ray3D &ray )
   147     QDebugStateSaver saver( dbg );
   148     dbg.nospace() << 
"QRay3D(origin("   149                   << ray.origin().x() << 
", " << ray.origin().y() << 
", "   150                   << ray.origin().z() << 
") - direction("   151                   << ray.direction().x() << 
", " << ray.direction().y() << 
", "   152                   << ray.direction().z() << 
"))";
   175   ray( 
double xO, 
double yO, 
double zO, 
double xD, 
double yD, 
double zD )
   177     origin[0] = xO; origin[1] = yO; origin[2] = zO;
   178     dir[0] = xD; dir[1] = yD; dir[2] = zD;
   179     dir_inv[0] = 1 / dir[0]; dir_inv[1] = 1 / dir[1]; dir_inv[2] = 1 / dir[2];
   181   ray( 
const QgsRayCastingUtils::Ray3D &r )
   184     origin[0] = r.origin().x(); origin[1] = r.origin().y(); origin[2] = r.origin().z();
   185     dir[0] = r.direction().x(); dir[1] = r.direction().y(); dir[2] = r.direction().z();
   186     dir_inv[0] = 1 / dir[0]; dir_inv[1] = 1 / dir[1]; dir_inv[2] = 1 / dir[2];
   196 bool intersection( 
const box &b, 
const ray &r )
   198   double t1 = ( b.min[0] - r.origin[0] ) * r.dir_inv[0];
   199   double t2 = ( b.max[0] - r.origin[0] ) * r.dir_inv[0];
   201   double tmin = std::min( t1, t2 );
   202   double tmax = std::max( t1, t2 );
   204   for ( 
int i = 1; i < 3; ++i )
   206     t1 = ( b.min[i] - r.origin[i] ) * r.dir_inv[i];
   207     t2 = ( b.max[i] - r.origin[i] ) * r.dir_inv[i];
   209     tmin = std::max( tmin, std::min( std::min( t1, t2 ), tmax ) );
   210     tmax = std::min( tmax, std::max( std::max( t1, t2 ), tmin ) );
   213   return tmax > std::max( tmin, 0.0 );
   217 namespace QgsRayCastingUtils
   220   bool rayBoxIntersection( 
const Ray3D &r, 
const QgsAABB &aabb )
   225     if ( b.min[0] == b.max[0] ) b.max[0] += 0.1;
   226     if ( b.min[1] == b.max[1] ) b.max[1] += 0.1;
   227     if ( b.min[2] == b.max[2] ) b.max[2] += 0.1;
   229     return intersection( b, ray( r ) );
   233   bool rayPlaneIntersection( 
const Ray3D &r, 
const Plane3D &plane, QVector3D &pt )
   235     float denom = QVector3D::dotProduct( plane.normal, r.direction() );
   236     if ( std::abs( denom ) > 0.0001f ) 
   238       float t = QVector3D::dotProduct( plane.center - r.origin(), plane.normal ) / denom;
   250   bool rayTriangleIntersection( 
const Ray3D &ray,
   260     const QVector3D ab = b - a;
   261     const QVector3D ac = c - a;
   262     const QVector3D qp = ( ray.origin() - ray.point( ray.distance() ) );
   264     const QVector3D n = QVector3D::crossProduct( ab, ac );
   265     const float d = QVector3D::dotProduct( qp, n );
   270     const QVector3D ap = ray.origin() - a;
   271     t = QVector3D::dotProduct( ap, n );
   273     if ( t < 0.0f || t > d )
   276     const QVector3D e = QVector3D::crossProduct( qp, ap );
   277     uvw.setY( QVector3D::dotProduct( ac, e ) );
   279     if ( uvw.y() < 0.0f || uvw.y() > d )
   282     uvw.setZ( -QVector3D::dotProduct( ab, e ) );
   284     if ( uvw.z() < 0.0f || uvw.y() + uvw.z() > d )
   287     const float ood = 1.0f / d;
   289     uvw.setY( uvw.y() * ood );
   290     uvw.setZ( uvw.z() * ood );
   291     uvw.setX( 1.0f - uvw.y() - uvw.z() );
   303 static QRect windowViewport( QSize area, 
const QRectF &relativeViewport )
   305   if ( area.isValid() )
   307     const int areaWidth = area.width();
   308     const int areaHeight = area.height();
   309     return QRect( relativeViewport.x() * areaWidth,
   310                   ( 1.0 - relativeViewport.y() - relativeViewport.height() ) * areaHeight,
   311                   relativeViewport.width() * areaWidth,
   312                   relativeViewport.height() * areaHeight );
   314   return relativeViewport.toRect();
   318 static QgsRayCastingUtils::Ray3D intersectionRay( QPointF pos, 
const QMatrix4x4 &viewMatrix,
   319     const QMatrix4x4 &projectionMatrix, QRect viewport )
   326   QVector3D nearPos = QVector3D( pos.x(), pos.y(), 0.0f );
   327   nearPos = nearPos.unproject( viewMatrix, projectionMatrix, viewport );
   328   QVector3D farPos = QVector3D( pos.x(), pos.y(), 1.0f );
   329   farPos = farPos.unproject( viewMatrix, projectionMatrix, viewport );
   331   return QgsRayCastingUtils::Ray3D( nearPos,
   332                                     ( farPos - nearPos ).normalized(),
   333                                     ( farPos - nearPos ).length() );
   337 namespace QgsRayCastingUtils
   340   Ray3D rayForViewportAndCamera( QSize area,
   342                                  const QRectF &relativeViewport,
   343                                  const Qt3DRender::QCamera *camera )
   345     QMatrix4x4 viewMatrix = camera->viewMatrix();
   346     QMatrix4x4 projectionMatrix = camera->projectionMatrix();
   347     const QRect viewport = windowViewport( area, relativeViewport );
   350     const QPointF glCorrectPos = QPointF( pos.x(), area.isValid() ? area.height() - pos.y() : pos.y() );
   351     const auto ray = intersectionRay( glCorrectPos, viewMatrix, projectionMatrix, viewport );
   355   Ray3D rayForCameraCenter( 
const Qt3DRender::QCamera *camera )
   357     QMatrix4x4 inverse = QMatrix4x4( camera->projectionMatrix() * camera->viewMatrix() ).inverted();
   359     QVector4D vNear( 0.0, 0.0, -1.0, 1.0 );
   360     QVector4D vFar( 0.0, 0.0, 1.0, 1.0 );
   361     QVector4D nearPos4D = inverse * vNear;
   362     QVector4D farPos4D = inverse * vFar;
   371     QVector3D nearPos( ( nearPos4D / nearPos4D.w() ).toVector3D() );
   372     QVector3D farPos( ( farPos4D / farPos4D.w() ).toVector3D() );
   374     return QgsRayCastingUtils::Ray3D( nearPos,
   375                                       ( farPos - nearPos ).normalized(),
   376                                       ( farPos - nearPos ).length() );
 3 Axis-aligned bounding box - in world coords. 
 
bool qgsFloatNear(float a, float b, float epsilon=4 *FLT_EPSILON)
Compare two floats (but allow some difference) 
 
bool operator==(const QgsFeatureIterator &fi1, const QgsFeatureIterator &fi2)
 
bool operator!=(const QgsFeatureIterator &fi1, const QgsFeatureIterator &fi2)
 
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
 
std::ostream & operator<<(std::ostream &os, const QgsCoordinateReferenceSystem &r)
Output stream operator.