Skip to content
Permalink
Browse files

probably working but 90% sure there are bugs

  • Loading branch information
NEDJIMAbelgacem authored and wonder-sk committed Feb 10, 2021
1 parent 81fe1c2 commit fdf379a10e204c16471a69d85685afc2bf98e402
@@ -29,6 +29,8 @@

#include "qgseventtracing.h"

#include <queue>

///@cond PRIVATE

static float screenSpaceError( float epsilon, float distance, float screenSize, float fov )
@@ -142,19 +144,6 @@ void QgsChunkedEntity::update( const SceneState &state )

int enabled = 0, disabled = 0, unloaded = 0;

QList<QgsChunkNode *> newActiveNodes;
int rendered = 0;
for ( QgsChunkNode *node : mActiveNodes )
{
QgsChunkLoader *nodeLoader = mChunkLoaderFactory->createChunkLoader( node );
if ( nodeLoader->primitiveCount() + rendered > nodeLoader->primitiveBudget() )
break;
rendered += nodeLoader->primitiveCount();
newActiveNodes.append( node );
}

mActiveNodes = newActiveNodes;

for ( QgsChunkNode *node : mActiveNodes )
{
if ( activeBefore.contains( node ) )
@@ -255,88 +244,93 @@ int QgsChunkedEntity::pendingJobsCount() const
return mChunkLoaderQueue->count() + mActiveJobs.count();
}


void QgsChunkedEntity::update( QgsChunkNode *root, const SceneState &state )
{
using slot = std::pair<QgsChunkNode *, float>;
auto cmp_funct = []( std::pair<QgsChunkNode *, float> p1, std::pair<QgsChunkNode *, float> p2 )
{
return p1.second < p2.second;
};
int renderedCount = 0;
QVector<QgsChunkNode *> currentNodes;
currentNodes.append( root );
while ( !currentNodes.empty() )
std::priority_queue<slot, std::vector<slot>, decltype( cmp_funct )> pq( cmp_funct );
pq.push( std::make_pair( root, screenSpaceError( root, state ) ) );
while ( !pq.empty() )
{
QVector<QgsChunkNode *> nextNodes;
for ( QgsChunkNode * node : currentNodes )
slot s = pq.top();
pq.pop();
QgsChunkNode *node = s.first;
QgsChunkLoader *nodeLoader = mChunkLoaderFactory->createChunkLoader( node );

if ( Qgs3DUtils::isCullable( node->bbox(), state.viewProjectionMatrix ) )
{
QgsChunkLoader *nodeLoader = mChunkLoaderFactory->createChunkLoader( node );
++mFrustumCulled;
continue;
}

if ( Qgs3DUtils::isCullable( node->bbox(), state.viewProjectionMatrix ) )
{
++mFrustumCulled;
continue;
}
// ensure we have child nodes (at least skeletons) available, if any
if ( node->childCount() == -1 )
{
node->populateChildren( mChunkLoaderFactory->createChildren( node ) );
}

// ensure we have child nodes (at least skeletons) available, if any
if ( node->childCount() == -1 )
{
node->populateChildren( mChunkLoaderFactory->createChildren( node ) );
}
// make sure all nodes leading to children are always loaded
// so that zooming out does not create issues
requestResidency( node );

// make sure all nodes leading to children are always loaded
// so that zooming out does not create issues
requestResidency( node );
if ( !node->entity() )
{
// this happens initially when root node is not ready yet
continue;
}

if ( !node->entity() )
{
// this happens initially when root node is not ready yet
continue;
}
if ( renderedCount + nodeLoader->primitiveCount() > nodeLoader->primitiveBudget() )
continue;

//QgsDebugMsgLevel( QStringLiteral( "%1|%2|%3 %4 %5" ).arg( node->tileX() ).arg( node->tileY() ).arg( node->tileZ() ).arg( mTau ).arg( screenSpaceError( node, state ) ), 2 );
if ( node->childCount() == 0 )
{
if ( nodeLoader != nullptr )
renderedCount += nodeLoader->primitiveCount();
// 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...
mActiveNodes << node;
}
else if ( mTau > 0 && screenSpaceError( node, state ) <= mTau )

//QgsDebugMsgLevel( QStringLiteral( "%1|%2|%3 %4 %5" ).arg( node->tileX() ).arg( node->tileY() ).arg( node->tileZ() ).arg( mTau ).arg( screenSpaceError( node, state ) ), 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...
renderedCount += nodeLoader->primitiveCount();
mActiveNodes << node;
}
else if ( mTau > 0 && screenSpaceError( node, state ) <= mTau )
{
// acceptable error for the current chunk - let's render it
renderedCount += nodeLoader->primitiveCount();
mActiveNodes << node;
}
else if ( node->allChildChunksResident( mCurrentTime ) )
{
// error is not acceptable and children are ready to be used - recursive descent

if ( mAdditiveStrategy )
{
// acceptable error for the current chunk - let's render it
// With additive strategy enabled, also all parent nodes are added to active nodes.
// This is desired when child nodes add more detailed data rather than just replace
// coarser data in parents. We use this e.g. with point cloud data.
renderedCount += nodeLoader->primitiveCount();
mActiveNodes << node;
}
else if ( node->allChildChunksResident( mCurrentTime ) )

QgsChunkNode *const *children = node->children();
for ( int i = 0; i < node->childCount(); ++i )
{
// error is not acceptable and children are ready to be used - recursive descent


if ( mAdditiveStrategy )
{
// With additive strategy enabled, also all parent nodes are added to active nodes.
// This is desired when child nodes add more detailed data rather than just replace
// coarser data in parents. We use this e.g. with point cloud data.
mActiveNodes << node;
}

QgsChunkNode *const *children = node->children();
for ( int i = 0; i < node->childCount(); ++i )
{
nextNodes.push_back( children[ i ] );
}
pq.push( std::make_pair( children[i], screenSpaceError( children[i], state ) ) );
}
else
{
// error is not acceptable but children are not ready either - still use parent but request children
mActiveNodes << node;
}
else
{
// error is not acceptable but children are not ready either - still use parent but request children
renderedCount += nodeLoader->primitiveCount();
mActiveNodes << node;

QgsChunkNode *const *children = node->children();
for ( int i = 0; i < node->childCount(); ++i )
requestResidency( children[i] );
}
QgsChunkNode *const *children = node->children();
for ( int i = 0; i < node->childCount(); ++i )
requestResidency( children[i] );
}
currentNodes = nextNodes;
}

// qDebug() << "Rendered points: " << renderedCount;
}


@@ -383,12 +383,15 @@ void addQLayerComponentsToHierarchy( Qt3DCore::QEntity *entity, const QVector<Qt

void Qgs3DMapScene::updateScene()
{
QElapsedTimer t;
t.start();
QgsEventTracing::addEvent( QgsEventTracing::Instant, QStringLiteral( "3D" ), QStringLiteral( "Update Scene" ) );
for ( QgsChunkedEntity *entity : qgis::as_const( mChunkEntities ) )
{
if ( entity->isEnabled() )
entity->update( _sceneState( mCameraController ) );
}
qDebug() << "Time taken to update" << t.elapsed();
#if QT_VERSION < QT_VERSION_CHECK(5, 10, 0)
QgsWindow3DEngine *windowEngine = qobject_cast<QgsWindow3DEngine *>( mEngine );
if ( windowEngine != nullptr )
@@ -148,9 +148,10 @@ QgsPointCloudLayerChunkLoaderFactory::QgsPointCloudLayerChunkLoaderFactory( cons
QgsChunkLoader *QgsPointCloudLayerChunkLoaderFactory::createChunkLoader( QgsChunkNode *node ) const
{
QgsChunkNodeId id = node->tileId();
Q_ASSERT( mPointCloudIndex->hasNode( IndexedPointCloudNode( id.d, id.x, id.y, id.z ) ) );
QgsPointCloudBlock *block = mPointCloudIndex->nodeData( IndexedPointCloudNode( id.d, id.x, id.y, id.z ), QgsPointCloudRequest() );
return new QgsPointCloudLayerChunkLoader( this, node, std::unique_ptr< QgsPointCloud3DSymbol >( static_cast< QgsPointCloud3DSymbol * >( mSymbol->clone() ) ), mZValueScale, mZValueOffset, mPointBudget, block->pointCount() );
IndexedPointCloudNode n( id.d, id.x, id.y, id.z );
Q_ASSERT( mPointCloudIndex->hasNode( n ) );
int pointCount = mPointCloudIndex->nodePointCount( n );
return new QgsPointCloudLayerChunkLoader( this, node, std::unique_ptr< QgsPointCloud3DSymbol >( static_cast< QgsPointCloud3DSymbol * >( mSymbol->clone() ) ), mZValueScale, mZValueOffset, mPointBudget, pointCount );
}

QgsAABB nodeBoundsToAABB( QgsPointCloudDataBounds nodeBounds, QgsVector3D offset, QgsVector3D scale, const Qgs3DMapSettings &map, double zValueOffset );
@@ -228,3 +228,10 @@ int QgsPointCloudIndex::span() const
{
return mSpan;
}

int QgsPointCloudIndex::nodePointCount( const IndexedPointCloudNode &n )
{
if ( !mHierarchy.contains( n ) )
return -1;
return mHierarchy[n];
}
@@ -222,6 +222,8 @@ class CORE_EXPORT QgsPointCloudIndex: public QObject
*/
int span() const;

int nodePointCount( const IndexedPointCloudNode &n );

protected: //TODO private
//! Sets native attributes of the data
void setAttributes( const QgsPointCloudAttributeCollection &attributes );

0 comments on commit fdf379a

Please sign in to comment.