17#include "qgsvirtualpointcloudprovider.h" 
   29    float maximumScreenSpaceError,
 
   30    bool showBoundingBoxes,
 
   34  : Qgs3DMapSceneEntity( nullptr )
 
   37  , mCoordinateTransform( coordinateTransform )
 
   38  , mZValueScale( zValueScale )
 
   39  , mZValueOffset( zValueOffset )
 
   40  , mPointBudget( pointBudget )
 
   41  , mMaximumScreenSpaceError( maximumScreenSpaceError )
 
   42  , mShowBoundingBoxes( showBoundingBoxes )
 
   44  mSymbol.reset( symbol );
 
   45  mBboxesEntity = 
new QgsChunkBoundsEntity( 
this );
 
   47  const QVector<QgsPointCloudSubIndex> subIndexes = provider()->subIndexes();
 
   48  for ( 
int i = 0; i < subIndexes.size(); ++i )
 
   50    const QgsPointCloudSubIndex &si = subIndexes.at( i );
 
   55    createChunkedEntityForSubIndex( i );
 
   59  connect( 
this, &QgsVirtualPointCloudEntity::subIndexNeedsLoading, provider(), &QgsVirtualPointCloudProvider::loadSubIndex, Qt::QueuedConnection );
 
   60  connect( provider(), &QgsVirtualPointCloudProvider::subIndexLoaded, 
this, &QgsVirtualPointCloudEntity::createChunkedEntityForSubIndex );
 
   64QList<QgsChunkedEntity *> QgsVirtualPointCloudEntity::chunkedEntities()
 const 
   66  return mChunkedEntitiesMap.values();
 
   69QgsVirtualPointCloudProvider *QgsVirtualPointCloudEntity::provider()
 const 
   71  return qobject_cast<QgsVirtualPointCloudProvider *>( mLayer->dataProvider() );
 
   74QgsAABB QgsVirtualPointCloudEntity::boundingBox( 
int i )
 const 
   76  return mBboxes.at( i );
 
   79void QgsVirtualPointCloudEntity::createChunkedEntityForSubIndex( 
int i )
 
   81  const QVector<QgsPointCloudSubIndex> subIndexes = provider()->subIndexes();
 
   82  const QgsPointCloudSubIndex &si = subIndexes.at( i );
 
   85  if ( !si.index() || mBboxes.at( i ).isEmpty() )
 
   88  QgsPointCloudLayerChunkedEntity *newChunkedEntity = 
new QgsPointCloudLayerChunkedEntity( si.index(),
 
   92      mMaximumScreenSpaceError,
 
   98  mChunkedEntitiesMap.insert( i, newChunkedEntity );
 
   99  newChunkedEntity->setParent( 
this );
 
  100  connect( newChunkedEntity, &QgsChunkedEntity::pendingJobsCountChanged, 
this, &Qgs3DMapSceneEntity::pendingJobsCountChanged );
 
  101  emit newEntityCreated( newChunkedEntity );
 
  104void QgsVirtualPointCloudEntity::handleSceneUpdate( 
const SceneContext &sceneContext )
 
  106  const QVector<QgsPointCloudSubIndex> subIndexes = provider()->subIndexes();
 
  107  for ( 
int i = 0; i < subIndexes.size(); ++i )
 
  109    const QgsAABB &bbox = mBboxes.at( i );
 
  115    constexpr int SPAN = 256;
 
  116    const float epsilon = std::min( bbox.
xExtent(), bbox.
yExtent() ) / SPAN;
 
  119    constexpr float THRESHOLD = .2;
 
  123    const bool displayAsBbox = sceneContext.cameraPos.isNull() || sse < THRESHOLD;
 
  124    if ( !displayAsBbox && !subIndexes.at( i ).index() )
 
  125      emit subIndexNeedsLoading( i );
 
  127    setRenderSubIndexAsBbox( i, displayAsBbox );
 
  128    if ( !displayAsBbox && mChunkedEntitiesMap.contains( i ) )
 
  129      mChunkedEntitiesMap[i]->handleSceneUpdate( sceneContext );
 
  134QgsRange<float> QgsVirtualPointCloudEntity::getNearFarPlaneRange( 
const QMatrix4x4 &viewMatrix )
 const 
  139  for ( QgsChunkedEntity *entity : mChunkedEntitiesMap )
 
  141    if ( entity->isEnabled() )
 
  143      const QgsRange<float> range = entity->getNearFarPlaneRange( viewMatrix );
 
  144      ffar = std::max( range.
upper(), ffar );
 
  145      fnear = std::min( range.
lower(), fnear );
 
  150  if ( fnear == 1e9 && ffar == 0 )
 
  152    for ( 
const QgsAABB &bbox : mBboxes )
 
  157      fnear = std::min( fnear, bboxfnear );
 
  158      ffar = std::max( ffar, bboxffar );
 
  165int QgsVirtualPointCloudEntity::pendingJobsCount()
 const 
  168  for ( QgsChunkedEntity *entity : mChunkedEntitiesMap )
 
  170    if ( entity->isEnabled() )
 
  171      jobs += entity->pendingJobsCount();
 
  176bool QgsVirtualPointCloudEntity::needsUpdate()
 const 
  178  for ( QgsChunkedEntity *entity : mChunkedEntitiesMap )
 
  180    if ( entity->isEnabled() && entity->needsUpdate() )
 
  186void QgsVirtualPointCloudEntity::updateBboxEntity()
 
  188  QList<QgsAABB> bboxes;
 
  189  const QVector<QgsPointCloudSubIndex> subIndexes = provider()->subIndexes();
 
  190  for ( 
int i = 0; i < subIndexes.size(); ++i )
 
  192    if ( mChunkedEntitiesMap.contains( i ) && mChunkedEntitiesMap[i]->isEnabled() )
 
  195    if ( mBboxes.at( i ).isEmpty() )
 
  198    bboxes << mBboxes.at( i );
 
  201  mBboxesEntity->setBoxes( bboxes );
 
  204void QgsVirtualPointCloudEntity::setRenderSubIndexAsBbox( 
int i, 
bool asBbox )
 
  206  if ( !mChunkedEntitiesMap.contains( i ) )
 
  209  mChunkedEntitiesMap[i]->setEnabled( !asBbox );
 
static QgsAABB mapToWorldExtent(const QgsRectangle &extent, double zMin, double zMax, const QgsVector3D &mapOrigin)
Converts map extent to axis aligned bounding box in 3D world coordinates.
 
static float screenSpaceError(float epsilon, float distance, int screenSize, float fov)
This routine approximately calculates how an error (epsilon) of an object in world coordinates at giv...
 
static QgsRectangle tryReprojectExtent2D(const QgsRectangle &extent, const QgsCoordinateReferenceSystem &crs1, const QgsCoordinateReferenceSystem &crs2, const QgsCoordinateTransformContext &context)
Reprojects extent from crs1 to crs2 coordinate reference system with context context.
 
static void computeBoundingBoxNearFarPlanes(const QgsAABB &bbox, const QMatrix4x4 &viewMatrix, float &fnear, float &ffar)
This routine computes nearPlane farPlane from the closest and farthest corners point of bounding box ...
 
float yExtent() const
Returns box width in Y axis.
 
float xExtent() const
Returns box width in X axis.
 
bool isEmpty() const
Returns true if xExtent(), yExtent() and zExtent() are all zero, false otherwise.
 
float distanceFromPoint(float x, float y, float z) const
Returns shortest distance from the box to a point.
 
QgsCoordinateReferenceSystem crs
 
Represents a map layer supporting display of point clouds.
 
A template based class for storing ranges (lower to upper values).
 
T lower() const
Returns the lower bound of the range.
 
T upper() const
Returns the upper bound of the range.
 
A rectangle specified with double values.
 
QgsRectangle intersect(const QgsRectangle &rect) const
Returns the intersection with the given rectangle.