Skip to content

Commit

Permalink
Fix(3D): rename Qgs3DMapSceneEntity::SceneState to SceneContext to av…
Browse files Browse the repository at this point in the history
…oid confusion with Qgs3DMapScene::SceneState
  • Loading branch information
benoitdm-oslandia authored and troopa81 committed Dec 18, 2023
1 parent 47b0fac commit 9de7e13
Show file tree
Hide file tree
Showing 7 changed files with 43 additions and 42 deletions.
38 changes: 19 additions & 19 deletions src/3d/chunks/qgschunkedentity_p.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,16 @@
///@cond PRIVATE


static float screenSpaceError( QgsChunkNode *node, const QgsChunkedEntity::SceneState &state )
static float screenSpaceError( QgsChunkNode *node, const QgsChunkedEntity::SceneContext &sceneContext )
{
if ( node->error() <= 0 ) //it happens for meshes
return 0;

float dist = node->bbox().distanceFromPoint( state.cameraPos );
float dist = node->bbox().distanceFromPoint( sceneContext.cameraPos );

// TODO: what to do when distance == 0 ?

float sse = Qgs3DUtils::screenSpaceError( node->error(), dist, state.screenSizePx, state.cameraFov );
float sse = Qgs3DUtils::screenSpaceError( node->error(), dist, sceneContext.screenSizePx, sceneContext.cameraFov );
return sse;
}

Expand Down Expand Up @@ -120,7 +120,7 @@ QgsChunkedEntity::~QgsChunkedEntity()
}


void QgsChunkedEntity::handleSceneUpdate( const SceneState &state )
void QgsChunkedEntity::handleSceneUpdate( const SceneContext &sceneContext )
{
if ( !mIsValid )
return;
Expand All @@ -130,7 +130,7 @@ void QgsChunkedEntity::handleSceneUpdate( const SceneState &state )
// of the camera). Removing them keeps the loading queue shorter,
// and we avoid loading chunks that we only wanted for a short period
// of time when camera was moving.
pruneLoaderQueue( state );
pruneLoaderQueue( sceneContext );

QElapsedTimer t;
t.start();
Expand All @@ -142,7 +142,7 @@ void QgsChunkedEntity::handleSceneUpdate( const SceneState &state )
mFrustumCulled = 0;
mCurrentTime = QTime::currentTime();

update( mRootNode, state );
update( mRootNode, sceneContext );

#ifdef QGISDEBUG
int enabled = 0, disabled = 0, unloaded = 0;
Expand Down Expand Up @@ -333,7 +333,7 @@ void QgsChunkedEntity::updateNodes( const QList<QgsChunkNode *> &nodes, QgsChunk
startJobs();
}

void QgsChunkedEntity::pruneLoaderQueue( const SceneState &state )
void QgsChunkedEntity::pruneLoaderQueue( const SceneContext &sceneContext )
{
QList<QgsChunkNode *> toRemoveFromLoaderQueue;

Expand All @@ -344,7 +344,7 @@ void QgsChunkedEntity::pruneLoaderQueue( const SceneState &state )
while ( e )
{
Q_ASSERT( e->chunk->state() == QgsChunkNode::QueuedForLoad || e->chunk->state() == QgsChunkNode::QueuedForUpdate );
if ( Qgs3DUtils::isCullable( e->chunk->bbox(), state.viewProjectionMatrix ) )
if ( Qgs3DUtils::isCullable( e->chunk->bbox(), sceneContext.viewProjectionMatrix ) )
{
toRemoveFromLoaderQueue.append( e->chunk );
}
Expand Down Expand Up @@ -405,7 +405,7 @@ struct
}
} ResidencyRequestSorter;

void QgsChunkedEntity::update( QgsChunkNode *root, const SceneState &state )
void QgsChunkedEntity::update( QgsChunkNode *root, const SceneContext &sceneContext )
{
QSet<QgsChunkNode *> nodes;
QVector<ResidencyRequest> residencyRequests;
Expand All @@ -417,14 +417,14 @@ void QgsChunkedEntity::update( QgsChunkNode *root, const SceneState &state )
};
int renderedCount = 0;
std::priority_queue<slotItem, std::vector<slotItem>, decltype( cmp_funct )> pq( cmp_funct );
pq.push( std::make_pair( root, screenSpaceError( root, state ) ) );
pq.push( std::make_pair( root, screenSpaceError( root, sceneContext ) ) );
while ( !pq.empty() && renderedCount <= mPrimitivesBudget )
{
slotItem s = pq.top();
pq.pop();
QgsChunkNode *node = s.first;

if ( Qgs3DUtils::isCullable( node->bbox(), state.viewProjectionMatrix ) )
if ( Qgs3DUtils::isCullable( node->bbox(), sceneContext.viewProjectionMatrix ) )
{
++mFrustumCulled;
continue;
Expand Down Expand Up @@ -453,7 +453,7 @@ void QgsChunkedEntity::update( QgsChunkNode *root, const SceneState &state )

// make sure all nodes leading to children are always loaded
// so that zooming out does not create issues
double dist = node->bbox().center().distanceToPoint( state.cameraPos );
double dist = node->bbox().center().distanceToPoint( sceneContext.cameraPos );
residencyRequests.push_back( ResidencyRequest( node, dist, node->level() ) );

if ( !node->entity() )
Expand All @@ -463,14 +463,14 @@ void QgsChunkedEntity::update( QgsChunkNode *root, const SceneState &state )
}
bool becomesActive = false;

// QgsDebugMsgLevel( QStringLiteral( "%1|%2|%3 %4 %5" ).arg( node->tileId().x ).arg( node->tileId().y ).arg( node->tileId().z ).arg( mTau ).arg( screenSpaceError( node, state ) ), 2 );
// QgsDebugMsgLevel( QStringLiteral( "%1|%2|%3 %4 %5" ).arg( node->tileId().x ).arg( node->tileId().y ).arg( node->tileId().z ).arg( mTau ).arg( screenSpaceError( node, sceneContext ) ), 2 );
if ( node->childCount() == 0 )
{
// there's no children available for this node, so regardless of whether it has an acceptable error
// or not, it's the best we'll ever get...
becomesActive = true;
}
else if ( mTau > 0 && screenSpaceError( node, state ) <= mTau )
else if ( mTau > 0 && screenSpaceError( node, sceneContext ) <= mTau )
{
// acceptable error for the current chunk - let's render it
becomesActive = true;
Expand All @@ -495,15 +495,15 @@ void QgsChunkedEntity::update( QgsChunkNode *root, const SceneState &state )
if ( children[i]->entity() || !children[i]->hasData() )
{
// chunk is resident - let's visit it recursively
pq.push( std::make_pair( children[i], screenSpaceError( children[i], state ) ) );
pq.push( std::make_pair( children[i], screenSpaceError( children[i], sceneContext ) ) );
}
else
{
// chunk is not yet resident - let's try to load it
if ( Qgs3DUtils::isCullable( children[i]->bbox(), state.viewProjectionMatrix ) )
if ( Qgs3DUtils::isCullable( children[i]->bbox(), sceneContext.viewProjectionMatrix ) )
continue;

double dist = children[i]->bbox().center().distanceToPoint( state.cameraPos );
double dist = children[i]->bbox().center().distanceToPoint( sceneContext.cameraPos );
residencyRequests.push_back( ResidencyRequest( children[i], dist, children[i]->level() ) );
}
}
Expand All @@ -517,7 +517,7 @@ void QgsChunkedEntity::update( QgsChunkNode *root, const SceneState &state )
{
QgsChunkNode *const *children = node->children();
for ( int i = 0; i < node->childCount(); ++i )
pq.push( std::make_pair( children[i], screenSpaceError( children[i], state ) ) );
pq.push( std::make_pair( children[i], screenSpaceError( children[i], sceneContext ) ) );
}
else
{
Expand All @@ -526,7 +526,7 @@ void QgsChunkedEntity::update( QgsChunkNode *root, const SceneState &state )
QgsChunkNode *const *children = node->children();
for ( int i = 0; i < node->childCount(); ++i )
{
double dist = children[i]->bbox().center().distanceToPoint( state.cameraPos );
double dist = children[i]->bbox().center().distanceToPoint( sceneContext.cameraPos );
residencyRequests.push_back( ResidencyRequest( children[i], dist, children[i]->level() ) );
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/3d/chunks/qgschunkedentity_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ class QgsChunkedEntity : public Qgs3DMapSceneEntity
~QgsChunkedEntity() override;

//! Called when e.g. camera changes and entity may need updated
void handleSceneUpdate( const SceneState &state ) override;
void handleSceneUpdate( const SceneContext &sceneContext ) override;

//! Returns number of jobs pending for this entity until it is fully loaded/updated in the current view
int pendingJobsCount() const override;
Expand Down Expand Up @@ -112,10 +112,10 @@ class QgsChunkedEntity : public Qgs3DMapSceneEntity
void setNeedsUpdate( bool needsUpdate ) { mNeedsUpdate = needsUpdate; }

private:
void update( QgsChunkNode *node, const SceneState &state );
void update( QgsChunkNode *node, const SceneContext &sceneContext );

//! Removes chunks for loading queue that are currently not needed
void pruneLoaderQueue( const SceneState &state );
void pruneLoaderQueue( const SceneContext &sceneContext );

//! make sure that the chunk will be loaded soon (if not loaded yet) and not unloaded anytime soon (if loaded already)
void requestResidency( QgsChunkNode *node );
Expand Down
22 changes: 11 additions & 11 deletions src/3d/qgs3dmapscene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -292,16 +292,16 @@ float Qgs3DMapScene::worldSpaceError( float epsilon, float distance ) const
return err;
}

Qgs3DMapSceneEntity::SceneState sceneState_( QgsAbstract3DEngine *engine )
Qgs3DMapSceneEntity::SceneContext Qgs3DMapScene::buildSceneContext( ) const
{
Qt3DRender::QCamera *camera = engine->camera();
Qgs3DMapSceneEntity::SceneState state;
state.cameraFov = camera->fieldOfView();
state.cameraPos = camera->position();
const QSize size = engine->size();
state.screenSizePx = std::max( size.width(), size.height() ); // TODO: is this correct?
state.viewProjectionMatrix = camera->projectionMatrix() * camera->viewMatrix();
return state;
Qt3DRender::QCamera *camera = mEngine->camera();
Qgs3DMapSceneEntity::SceneContext sceneContext;
sceneContext.cameraFov = camera->fieldOfView();
sceneContext.cameraPos = camera->position();
const QSize size = mEngine->size();
sceneContext.screenSizePx = std::max( size.width(), size.height() ); // TODO: is this correct?
sceneContext.viewProjectionMatrix = camera->projectionMatrix() * camera->viewMatrix();
return sceneContext;
}

void Qgs3DMapScene::onCameraChanged()
Expand Down Expand Up @@ -370,7 +370,7 @@ void Qgs3DMapScene::updateScene()

for ( Qgs3DMapSceneEntity *entity : std::as_const( mSceneEntities ) )
{
entity->handleSceneUpdate( sceneState_( mEngine ) );
entity->handleSceneUpdate( buildSceneContext() );
if ( entity->hasReachedGpuMemoryLimit() )
emit gpuMemoryLimitReached();
}
Expand Down Expand Up @@ -447,7 +447,7 @@ void Qgs3DMapScene::onFrameTriggered( float dt )
if ( entity->isEnabled() && entity->needsUpdate() )
{
QgsDebugMsgLevel( QStringLiteral( "need for update" ), 2 );
entity->handleSceneUpdate( sceneState_( mEngine ) );
entity->handleSceneUpdate( buildSceneContext() );
if ( entity->hasReachedGpuMemoryLimit() )
emit gpuMemoryLimitReached();
}
Expand Down
3 changes: 2 additions & 1 deletion src/3d/qgs3dmapscene.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

#include "qgsrectangle.h"
#include "qgscameracontroller.h"
#include "qgs3dmapsceneentity_p.h"

#ifndef SIP_RUN
namespace Qt3DRender
Expand Down Expand Up @@ -57,7 +58,6 @@ class QgsShadowRenderingFrameGraph;
class QgsPostprocessingEntity;
class QgsChunkNode;
class QgsDoubleRange;
class Qgs3DMapSceneEntity;


/**
Expand Down Expand Up @@ -280,6 +280,7 @@ class _3D_EXPORT Qgs3DMapScene : public QObject
void updateScene();
void finalizeNewEntity( Qt3DCore::QEntity *newEntity );
int maximumTextureSize() const;
Qgs3DMapSceneEntity::SceneContext buildSceneContext( ) const;

private:
Qgs3DMapSettings &mMap;
Expand Down
4 changes: 2 additions & 2 deletions src/3d/qgs3dmapsceneentity_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ class Qgs3DMapSceneEntity : public Qt3DCore::QEntity
}

//! Records some bits about the scene (context for handleSceneUpdate() method)
struct SceneState
struct SceneContext
{
QVector3D cameraPos; //!< Camera position
float cameraFov; //!< Field of view (in degrees)
Expand All @@ -64,7 +64,7 @@ class Qgs3DMapSceneEntity : public Qt3DCore::QEntity
};

//! Called when e.g. camera changes and entity may need updated
virtual void handleSceneUpdate( const SceneState &state ) { Q_UNUSED( state ) }
virtual void handleSceneUpdate( const SceneContext &sceneContext ) { Q_UNUSED( sceneContext ) }

//! Returns number of jobs pending for this entity until it is fully loaded/updated in the current view
virtual int pendingJobsCount() const { return 0; }
Expand Down
10 changes: 5 additions & 5 deletions src/3d/qgsvirtualpointcloudentity_p.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ void QgsVirtualPointCloudEntity::createChunkedEntityForSubIndex( int i )
emit newEntityCreated( newChunkedEntity );
}

void QgsVirtualPointCloudEntity::handleSceneUpdate( const SceneState &state )
void QgsVirtualPointCloudEntity::handleSceneUpdate( const SceneContext &sceneContext )
{
const QVector<QgsPointCloudSubIndex> subIndexes = provider()->subIndexes();
for ( int i = 0; i < subIndexes.size(); ++i )
Expand All @@ -114,19 +114,19 @@ void QgsVirtualPointCloudEntity::handleSceneUpdate( const SceneState &state )
// magic number 256 is the common span value for a COPC root node
constexpr int SPAN = 256;
const float epsilon = std::min( bbox.xExtent(), bbox.yExtent() ) / SPAN;
const float distance = bbox.distanceFromPoint( state.cameraPos );
const float sse = Qgs3DUtils::screenSpaceError( epsilon, distance, state.screenSizePx, state.cameraFov );
const float distance = bbox.distanceFromPoint( sceneContext.cameraPos );
const float sse = Qgs3DUtils::screenSpaceError( epsilon, distance, sceneContext.screenSizePx, sceneContext.cameraFov );
constexpr float THRESHOLD = .2;

// always display as bbox for the initial temporary camera pos (0, 0, 0)
// then once the camera changes we display as bbox depending on screen space error
const bool displayAsBbox = state.cameraPos.isNull() || sse < THRESHOLD;
const bool displayAsBbox = sceneContext.cameraPos.isNull() || sse < THRESHOLD;
if ( !displayAsBbox && !subIndexes.at( i ).index() )
emit subIndexNeedsLoading( i );

setRenderSubIndexAsBbox( i, displayAsBbox );
if ( !displayAsBbox && mChunkedEntitiesMap.contains( i ) )
mChunkedEntitiesMap[i]->handleSceneUpdate( state );
mChunkedEntitiesMap[i]->handleSceneUpdate( sceneContext );
}
updateBboxEntity();
}
Expand Down
2 changes: 1 addition & 1 deletion src/3d/qgsvirtualpointcloudentity_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ class QgsVirtualPointCloudEntity : public Qgs3DMapSceneEntity
double zValueScale, double zValueOffset, int pointBudget );

//! This is called when the camera moves. It's responsible for loading new indexes and decides if subindex will be rendered as bbox or chunked entity.
void handleSceneUpdate( const SceneState &state ) override;
void handleSceneUpdate( const SceneContext &sceneContext ) override;

QgsRange<float> getNearFarPlaneRange( const QMatrix4x4 &viewMatrix ) const override;

Expand Down

0 comments on commit 9de7e13

Please sign in to comment.