17#include "moc_qgsvirtualpointcloudentity_p.cpp"
18#include "qgsvirtualpointcloudprovider.h"
26QgsVirtualPointCloudEntity::QgsVirtualPointCloudEntity(
31 float maximumScreenSpaceError,
32 bool showBoundingBoxes,
37 : Qgs3DMapSceneEntity( map, nullptr )
39 , mCoordinateTransform( coordinateTransform )
40 , mZValueScale( zValueScale )
41 , mZValueOffset( zValueOffset )
42 , mPointBudget( pointBudget )
43 , mMaximumScreenSpaceError( maximumScreenSpaceError )
44 , mShowBoundingBoxes( showBoundingBoxes )
46 mSymbol.reset( symbol );
47 mBboxesEntity =
new QgsChunkBoundsEntity(
this );
49 const QVector<QgsPointCloudSubIndex> subIndexes = provider()->subIndexes();
50 for (
int i = 0; i < subIndexes.size(); ++i )
52 const QgsPointCloudSubIndex &si = subIndexes.at( i );
57 createChunkedEntityForSubIndex( i );
61 connect(
this, &QgsVirtualPointCloudEntity::subIndexNeedsLoading, provider(), &QgsVirtualPointCloudProvider::loadSubIndex, Qt::QueuedConnection );
62 connect( provider(), &QgsVirtualPointCloudProvider::subIndexLoaded,
this, &QgsVirtualPointCloudEntity::createChunkedEntityForSubIndex );
65QList<QgsChunkedEntity *> QgsVirtualPointCloudEntity::chunkedEntities()
const
67 return mChunkedEntitiesMap.values();
70QgsVirtualPointCloudProvider *QgsVirtualPointCloudEntity::provider()
const
72 return qobject_cast<QgsVirtualPointCloudProvider *>( mLayer->dataProvider() );
75QgsAABB QgsVirtualPointCloudEntity::boundingBox(
int i )
const
77 return mBboxes.at( i );
80void QgsVirtualPointCloudEntity::createChunkedEntityForSubIndex(
int i )
82 const QVector<QgsPointCloudSubIndex> subIndexes = provider()->subIndexes();
83 const QgsPointCloudSubIndex &si = subIndexes.at( i );
86 if ( !si.index() || mBboxes.at( i ).isEmpty() )
89 QgsPointCloudLayerChunkedEntity *newChunkedEntity =
new QgsPointCloudLayerChunkedEntity(
94 mMaximumScreenSpaceError,
101 mChunkedEntitiesMap.insert( i, newChunkedEntity );
102 newChunkedEntity->setParent(
this );
103 connect( newChunkedEntity, &QgsChunkedEntity::pendingJobsCountChanged,
this, &Qgs3DMapSceneEntity::pendingJobsCountChanged );
104 emit newEntityCreated( newChunkedEntity );
107void QgsVirtualPointCloudEntity::handleSceneUpdate(
const SceneContext &sceneContext )
109 const QVector<QgsPointCloudSubIndex> subIndexes = provider()->subIndexes();
110 for (
int i = 0; i < subIndexes.size(); ++i )
112 const QgsAABB &bbox = mBboxes.at( i );
118 constexpr int SPAN = 256;
119 const float epsilon = std::min( bbox.
xExtent(), bbox.
yExtent() ) / SPAN;
122 constexpr float THRESHOLD = .2;
126 const bool displayAsBbox = sceneContext.cameraPos.isNull() || sse < THRESHOLD;
127 if ( !displayAsBbox && !subIndexes.at( i ).index() )
128 emit subIndexNeedsLoading( i );
130 setRenderSubIndexAsBbox( i, displayAsBbox );
131 if ( !displayAsBbox && mChunkedEntitiesMap.contains( i ) )
132 mChunkedEntitiesMap[i]->handleSceneUpdate( sceneContext );
137QgsRange<float> QgsVirtualPointCloudEntity::getNearFarPlaneRange(
const QMatrix4x4 &viewMatrix )
const
142 for ( QgsChunkedEntity *entity : mChunkedEntitiesMap )
144 if ( entity->isEnabled() )
146 const QgsRange<float> range = entity->getNearFarPlaneRange( viewMatrix );
147 ffar = std::max( range.
upper(), ffar );
148 fnear = std::min( range.
lower(), fnear );
153 if ( fnear == 1e9 && ffar == 0 )
155 for (
const QgsAABB &bbox : mBboxes )
160 fnear = std::min( fnear, bboxfnear );
161 ffar = std::max( ffar, bboxffar );
168int QgsVirtualPointCloudEntity::pendingJobsCount()
const
171 for ( QgsChunkedEntity *entity : mChunkedEntitiesMap )
173 if ( entity->isEnabled() )
174 jobs += entity->pendingJobsCount();
179bool QgsVirtualPointCloudEntity::needsUpdate()
const
181 for ( QgsChunkedEntity *entity : mChunkedEntitiesMap )
183 if ( entity->isEnabled() && entity->needsUpdate() )
189void QgsVirtualPointCloudEntity::updateBboxEntity()
191 QList<QgsAABB> bboxes;
192 const QVector<QgsPointCloudSubIndex> subIndexes = provider()->subIndexes();
193 for (
int i = 0; i < subIndexes.size(); ++i )
195 if ( mChunkedEntitiesMap.contains( i ) && mChunkedEntitiesMap[i]->isEnabled() )
198 if ( mBboxes.at( i ).isEmpty() )
201 bboxes << mBboxes.at( i );
204 mBboxesEntity->setBoxes( bboxes );
207void QgsVirtualPointCloudEntity::setRenderSubIndexAsBbox(
int i,
bool asBbox )
209 if ( !mChunkedEntitiesMap.contains( i ) )
212 mChunkedEntitiesMap[i]->setEnabled( !asBbox );
QgsRectangle extent() const
Returns the 3D scene's 2D extent in the 3D scene's CRS.
QgsCoordinateReferenceSystem crs() const
Returns coordinate reference system used in the 3D scene.
QgsCoordinateTransformContext transformContext() const
Returns the coordinate transform context, which stores various information regarding which datum tran...
QgsVector3D origin() const
Returns coordinates in map CRS at which 3D scene has origin (0,0,0).
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.