void initializeScene() { SceneWindow *window = new SceneWindow(); //QWidget *container = QWidget::createWindowContainer(window); Qt3DCore::QAspectEngine engine; Qt3DInput::QInputAspect *inputAspect = new Qt3DInput::QInputAspect(); engine.registerAspect(new Qt3DRender::QRenderAspect()); engine.registerAspect(inputAspect); QVariantMap data; data.insert(QStringLiteral("surface"), QVariant::fromValue(static_cast<QSurface *>(window))); data.insert(QStringLiteral("eventSource"), QVariant::fromValue(window)); engine.setData(data); // root entity Qt3DCore::QEntity *sceneRoot = new Qt3DCore::QEntity(); // camera scene Qt3DCore::QCamera *camera = new Qt3DCore::QCamera(sceneRoot); camera->setFieldOfView(25); camera->setNearPlane(1); camera->setFarPlane(1000); camera->setViewCenter(QVector3D(0, 3, 0)); inputAspect->setCamera(camera); Qt3DRender::QFrameGraph *frameGraphComponent = new Qt3DRender::QFrameGraph(sceneRoot); Qt3DRender::QForwardRenderer *forwardRenderer = new Qt3DRender::QForwardRenderer(); forwardRenderer->setCamera(camera); forwardRenderer->setClearColor(Qt::blue); frameGraphComponent->setActiveFrameGraph(forwardRenderer); sceneRoot->addComponent(frameGraphComponent); // scene loader Qt3DCore::QEntity *sceneLoaderEntity = new Qt3DCore::QEntity(sceneRoot); Qt3DRender::QSceneLoader *sceneLoader = new Qt3DRender::QSceneLoader(sceneLoaderEntity); SceneHandler sceneHandler(sceneLoader); QObject::connect(sceneLoader, &Qt3DRender::QSceneLoader::statusChanged, &sceneHandler, &SceneHandler::onStatusChanged); sceneLoaderEntity->addComponent(sceneLoader); QUrl fileName; fileName = QUrl::fromLocalFile("file:://C:/Users/jacobmosehansen/Desktop/IKT/20mm_hollow_cube.stl"); sceneLoader->setSource(fileName); engine.setRootEntity(sceneRoot); }
int main(int ac, char **av) { QApplication app(ac, av); Qt3DExtras::Qt3DWindow view; view.defaultFrameGraph()->setClearColor(Qt::black); // Root entity Qt3DCore::QEntity *sceneRoot = new Qt3DCore::QEntity(); // Scene Camera Qt3DRender::QCamera *camera = view.camera(); camera->setProjectionType(Qt3DRender::QCameraLens::PerspectiveProjection); camera->setViewCenter(QVector3D(0.0f, 3.5f, 0.0f)); camera->setPosition(QVector3D(0.0f, 3.5f, 25.0f)); camera->setNearPlane(0.001f); camera->setFarPlane(10000.0f); // For camera controls Qt3DExtras::QFirstPersonCameraController *camController = new Qt3DExtras::QFirstPersonCameraController(sceneRoot); camController->setCamera(camera); // Scene loader Qt3DCore::QEntity *sceneLoaderEntity = new Qt3DCore::QEntity(sceneRoot); Qt3DRender::QSceneLoader *sceneLoader = new Qt3DRender::QSceneLoader(sceneLoaderEntity); SceneWalker sceneWalker(sceneLoader); QObject::connect(sceneLoader, &Qt3DRender::QSceneLoader::statusChanged, &sceneWalker, &SceneWalker::onStatusChanged); sceneLoaderEntity->addComponent(sceneLoader); QStringList args = QCoreApplication::arguments(); QUrl sourceFileName; if (args.count() <= 1) { QWidget *container = new QWidget(); QFileDialog dialog; dialog.setFileMode(QFileDialog::AnyFile); sourceFileName = dialog.getOpenFileUrl(container, QStringLiteral("Open a scene file")); } else { sourceFileName = QUrl::fromLocalFile(args[1]); } if (sourceFileName.isEmpty()) return 0; sceneLoader->setSource(sourceFileName); view.setRootEntity(sceneRoot); view.show(); return app.exec(); }
void SceneWalker::onStatusChanged() { qDebug() << "Status changed:" << m_loader->status(); if (m_loader->status() != Qt3DRender::QSceneLoader::Ready) return; // The QSceneLoader instance is a component of an entity. The loaded scene // tree is added under this entity. QVector<Qt3DCore::QEntity *> entities = m_loader->entities(); // Technically there could be multiple entities referencing the scene loader // but sharing is discouraged, and in our case there will be one anyhow. if (entities.isEmpty()) return; Qt3DCore::QEntity *root = entities[0]; // Print the tree. walkEntity(root); // To access a given node (like a named mesh in the scene), use QObject::findChild(). // The scene structure and names always depend on the asset. Qt3DCore::QEntity *e = root->findChild<Qt3DCore::QEntity *>(QStringLiteral("PlanePropeller_mesh")); // toyplane.obj if (e) qDebug() << "Found propeller node" << e << "with components" << e->components(); }
Qgs3DMapScene::Qgs3DMapScene( const Qgs3DMapSettings &map, QgsAbstract3DEngine *engine ) : mMap( map ) , mEngine( engine ) { connect( &map, &Qgs3DMapSettings::backgroundColorChanged, this, &Qgs3DMapScene::onBackgroundColorChanged ); onBackgroundColorChanged(); // TODO: strange - setting OnDemand render policy still keeps QGIS busy (Qt 5.9.0) // actually it is more busy than with the default "Always" policy although there are no changes in the scene. //mRenderer->renderSettings()->setRenderPolicy( Qt3DRender::QRenderSettings::OnDemand ); #if QT_VERSION >= 0x050900 // we want precise picking of terrain (also bounding volume picking does not seem to work - not sure why) mEngine->renderSettings()->pickingSettings()->setPickMethod( Qt3DRender::QPickingSettings::TrianglePicking ); #endif QRect viewportRect( QPoint( 0, 0 ), mEngine->size() ); // Camera float aspectRatio = ( float )viewportRect.width() / viewportRect.height(); mEngine->camera()->lens()->setPerspectiveProjection( mMap.fieldOfView(), aspectRatio, 10.f, 10000.0f ); mFrameAction = new Qt3DLogic::QFrameAction(); connect( mFrameAction, &Qt3DLogic::QFrameAction::triggered, this, &Qgs3DMapScene::onFrameTriggered ); addComponent( mFrameAction ); // takes ownership // Camera controlling mCameraController = new QgsCameraController( this ); // attaches to the scene mCameraController->setViewport( viewportRect ); mCameraController->setCamera( mEngine->camera() ); mCameraController->resetView( 1000 ); addCameraViewCenterEntity( mEngine->camera() ); // create terrain entity createTerrainDeferred(); connect( &map, &Qgs3DMapSettings::terrainGeneratorChanged, this, &Qgs3DMapScene::createTerrain ); connect( &map, &Qgs3DMapSettings::terrainVerticalScaleChanged, this, &Qgs3DMapScene::createTerrain ); connect( &map, &Qgs3DMapSettings::mapTileResolutionChanged, this, &Qgs3DMapScene::createTerrain ); connect( &map, &Qgs3DMapSettings::maxTerrainScreenErrorChanged, this, &Qgs3DMapScene::createTerrain ); connect( &map, &Qgs3DMapSettings::maxTerrainGroundErrorChanged, this, &Qgs3DMapScene::createTerrain ); connect( &map, &Qgs3DMapSettings::terrainShadingChanged, this, &Qgs3DMapScene::createTerrain ); connect( &map, &Qgs3DMapSettings::pointLightsChanged, this, &Qgs3DMapScene::updateLights ); connect( &map, &Qgs3DMapSettings::fieldOfViewChanged, this, &Qgs3DMapScene::updateCameraLens ); // create entities of renderers Q_FOREACH ( const QgsAbstract3DRenderer *renderer, map.renderers() ) { Qt3DCore::QEntity *newEntity = renderer->createEntity( map ); newEntity->setParent( this ); } // listen to changes of layers in order to add/remove 3D renderer entities connect( &map, &Qgs3DMapSettings::layersChanged, this, &Qgs3DMapScene::onLayersChanged ); updateLights(); #if 0 ChunkedEntity *testChunkEntity = new ChunkedEntity( AABB( -500, 0, -500, 500, 100, 500 ), 2.f, 3.f, 7, new TestChunkLoaderFactory ); testChunkEntity->setEnabled( false ); testChunkEntity->setParent( this ); chunkEntities << testChunkEntity; #endif connect( mCameraController, &QgsCameraController::cameraChanged, this, &Qgs3DMapScene::onCameraChanged ); connect( mCameraController, &QgsCameraController::viewportChanged, this, &Qgs3DMapScene::onCameraChanged ); #if 0 // experiments with loading of existing 3D models. // scene loader only gets loaded only when added to a scene... // it loads everything: geometries, materials, transforms, lights, cameras (if any) Qt3DCore::QEntity *loaderEntity = new Qt3DCore::QEntity; Qt3DRender::QSceneLoader *loader = new Qt3DRender::QSceneLoader; loader->setSource( QUrl( "file:///home/martin/Downloads/LowPolyModels/tree.dae" ) ); loaderEntity->addComponent( loader ); loaderEntity->setParent( this ); // mesh loads just geometry as one geometry... // so if there are different materials (e.g. colors) used in the model, this information is lost Qt3DCore::QEntity *meshEntity = new Qt3DCore::QEntity; Qt3DRender::QMesh *mesh = new Qt3DRender::QMesh; mesh->setSource( QUrl( "file:///home/martin/Downloads/LowPolyModels/tree.obj" ) ); meshEntity->addComponent( mesh ); Qt3DExtras::QPhongMaterial *material = new Qt3DExtras::QPhongMaterial; material->setAmbient( Qt::red ); meshEntity->addComponent( material ); Qt3DCore::QTransform *meshTransform = new Qt3DCore::QTransform; meshTransform->setScale( 1 ); meshEntity->addComponent( meshTransform ); meshEntity->setParent( this ); #endif if ( map.hasSkyboxEnabled() ) { Qt3DExtras::QSkyboxEntity *skybox = new Qt3DExtras::QSkyboxEntity; skybox->setBaseName( map.skyboxFileBase() ); skybox->setExtension( map.skyboxFileExtension() ); skybox->setParent( this ); // docs say frustum culling must be disabled for skybox. // it _somehow_ works even when frustum culling is enabled with some camera positions, // but then when zoomed in more it would disappear - so let's keep frustum culling disabled mEngine->setFrustumCullingEnabled( false ); } // force initial update of chunked entities onCameraChanged(); }