void checkCloning_data() { QTest::addColumn<Qt3DCore::QTransform *>("transform"); Qt3DCore::QTransform *defaultConstructed = new Qt3DCore::QTransform(); QTest::newRow("defaultConstructed") << defaultConstructed; Qt3DCore::QTransform *matrixPropertySet = new Qt3DCore::QTransform(); matrixPropertySet->setMatrix(Qt3DCore::QTransform::rotateAround(QVector3D(0.1877f, 0.6868f, 0.3884f), 45.0f, QVector3D(0.0f, 0.0f, 1.0f))); QTest::newRow("matrixPropertySet") << matrixPropertySet; Qt3DCore::QTransform *translationSet = new Qt3DCore::QTransform(); translationSet->setTranslation(QVector3D(0.1877f, 0.6868f, 0.3884f)); QTest::newRow("translationSet") << translationSet; Qt3DCore::QTransform *scaleSet = new Qt3DCore::QTransform(); scaleSet->setScale3D(QVector3D(0.1f, 0.6f, 0.3f)); QTest::newRow("scaleSet") << scaleSet; Qt3DCore::QTransform *rotationSet = new Qt3DCore::QTransform(); scaleSet->setRotation(Qt3DCore::QTransform::fromAxisAndAngle(0.0f, 0.0f, 1.0f, 30.0f)); QTest::newRow("rotationSet") << rotationSet; Qt3DCore::QTransform *eulerRotationSet = new Qt3DCore::QTransform(); eulerRotationSet->setRotationX(90.0f); eulerRotationSet->setRotationY(10.0f); eulerRotationSet->setRotationZ(1.0f); QTest::newRow("eulerRotationSet") << eulerRotationSet; }
void QgsPolygon3DSymbolEntity::addEntityForSelectedPolygons( const Qgs3DMapSettings &map, QgsVectorLayer *layer, const QgsPolygon3DSymbol &symbol ) { // build the default material Qt3DExtras::QPhongMaterial *mat = material( symbol ); // update the material with selection colors mat->setDiffuse( map.selectionColor() ); mat->setAmbient( map.selectionColor().darker() ); // build a transform function Qt3DCore::QTransform *tform = new Qt3DCore::QTransform; tform->setTranslation( QVector3D( 0, 0, 0 ) ); // build the feature request to select features QgsFeatureRequest req; req.setDestinationCrs( map.crs() ); req.setSubsetOfAttributes( _requiredAttributes( symbol, layer ), layer->fields() ); req.setFilterFids( layer->selectedFeatureIds() ); // build the entity QgsPolygon3DSymbolEntityNode *entity = new QgsPolygon3DSymbolEntityNode( map, layer, symbol, req ); entity->addComponent( mat ); entity->addComponent( tform ); entity->setParent( this ); }
Qt3DCore::QEntity *QgsDemTerrainTileLoader::createEntity( Qt3DCore::QEntity *parent ) { QgsTerrainTileEntity *entity = new QgsTerrainTileEntity; // create geometry renderer Qt3DRender::QGeometryRenderer *mesh = new Qt3DRender::QGeometryRenderer; mesh->setGeometry( new DemTerrainTileGeometry( mResolution, mHeightMap, mesh ) ); entity->addComponent( mesh ); // takes ownership if the component has no parent // create material createTextureComponent( entity ); // create transform Qt3DCore::QTransform *transform; transform = new Qt3DCore::QTransform(); entity->addComponent( transform ); float zMin, zMax; _heightMapMinMax( mHeightMap, zMin, zMax ); const Qgs3DMapSettings &map = terrain()->map3D(); QgsRectangle extent = map.terrainGenerator()->tilingScheme().tileToExtent( mNode->tileX(), mNode->tileY(), mNode->tileZ() ); //node->extent; double x0 = extent.xMinimum() - map.originX(); double y0 = extent.yMinimum() - map.originY(); double side = extent.width(); double half = side / 2; transform->setScale3D( QVector3D( side, map.terrainVerticalScale(), side ) ); transform->setTranslation( QVector3D( x0 + half, 0, - ( y0 + half ) ) ); mNode->setExactBbox( QgsAABB( x0, zMin * map.terrainVerticalScale(), -y0, x0 + side, zMax * map.terrainVerticalScale(), -( y0 + side ) ) ); entity->setEnabled( false ); entity->setParent( parent ); return entity; }
Transformer::Transformer() : m_bed(new Qt3DCore::QEntity()) { Qt3DRender::QPlaneMesh * cube = new Qt3DRender::QPlaneMesh(); cube->setWidth(20.0f); cube->setHeight(20.0f); cube->setMeshResolution(QSize(20,20)); m_bed->addComponent(cube); Qt3DCore::QTransform *cylinderTransform = new Qt3DCore::QTransform; cylinderTransform->setScale(1.0f); cylinderTransform->setRotation(QQuaternion::fromAxisAndAngle(QVector3D(1, 0, 0), 90.0f)); cylinderTransform->setTranslation(QVector3D{0,0,10}); m_material = new Qt3DRender::QPhongMaterial(); m_material->setAmbient(Qt::red); m_material->setDiffuse(Qt::red); m_material->setSpecular(Qt::black); m_material->setEnabled(true); m_bed->addComponent(m_material); }
Qt3DCore::QEntity *FlatTerrainChunkLoader::createEntity( Qt3DCore::QEntity *parent ) { QgsTerrainTileEntity *entity = new QgsTerrainTileEntity; // make geometry renderer // simple quad geometry shared by all tiles // QPlaneGeometry by default is 1x1 with mesh resolution QSize(2,2), centered at 0 // TODO: the geometry could be shared inside Terrain instance (within terrain-generator specific data?) mTileGeometry = new Qt3DExtras::QPlaneGeometry; Qt3DRender::QGeometryRenderer *mesh = new Qt3DRender::QGeometryRenderer; mesh->setGeometry( mTileGeometry ); // takes ownership if the component has no parent entity->addComponent( mesh ); // takes ownership if the component has no parent // create material createTextureComponent( entity ); // create transform Qt3DCore::QTransform *transform = nullptr; transform = new Qt3DCore::QTransform(); entity->addComponent( transform ); // set up transform according to the extent covered by the quad geometry QgsAABB bbox = mNode->bbox(); double side = bbox.xMax - bbox.xMin; double half = side / 2; transform->setScale( side ); transform->setTranslation( QVector3D( bbox.xMin + half, 0, bbox.zMin + half ) ); entity->setEnabled( false ); entity->setParent( parent ); return entity; }
void View3D::initLight() { //Setup light positions, intensities and color QList<QVector3D> lLightPositions; const QColor lightColor(255,255,255); const float lightIntensity = 0.2f; lLightPositions << QVector3D(-0.5,0,0) << QVector3D(0.5,0,0); /*<< QVector3D(0,0,-0.5) << QVector3D(0.5,0,0) << QVector3D(0,0,0.5) << QVector3D(0,0.5,0) << QVector3D(0,-0.5,0);*/ //Create all the lights - make it shine for(int i = 0; i < lLightPositions.size(); ++i) { //Light source Qt3DCore::QEntity* pLightEntity = new Qt3DCore::QEntity(m_pLightEntity); Qt3DCore::QTransform* pTransform = new Qt3DCore::QTransform(); pTransform->setTranslation(lLightPositions.at(i)); pLightEntity->addComponent(pTransform); Qt3DRender::QPointLight *pPointLight = new Qt3DRender::QPointLight(pLightEntity); pPointLight->setColor(lightColor); pPointLight->setIntensity(lightIntensity); pLightEntity->addComponent(pPointLight); m_lLightSources.append(pPointLight); //Uncomment the following to visualize the light sources for debugging: // Qt3DExtras::QSphereMesh* lightSphere = new Qt3DExtras::QSphereMesh(pLightEntity); // lightSphere->setRadius(0.1f); // pLightEntity->addComponent(lightSphere); // Qt3DExtras::QPhongMaterial* material = new Qt3DExtras::QPhongMaterial(pLightEntity); // material->setAmbient(lightColor); // pLightEntity->addComponent(material); } }
SceneModifier::SceneModifier(Qt3DCore::QEntity *rootEntity) : m_rootEntity(rootEntity) { // Torus shape data //! [0] m_torus = new Qt3DExtras::QTorusMesh(); m_torus->setRadius(1.0f); m_torus->setMinorRadius(0.4f); m_torus->setRings(100); m_torus->setSlices(20); //! [0] // TorusMesh Transform //! [1] Qt3DCore::QTransform *torusTransform = new Qt3DCore::QTransform(); torusTransform->setScale(2.0f); torusTransform->setRotation(QQuaternion::fromAxisAndAngle(QVector3D(0.0f, 1.0f, 0.0f), 25.0f)); torusTransform->setTranslation(QVector3D(5.0f, 4.0f, 0.0f)); //! [1] //! [2] Qt3DExtras::QPhongMaterial *torusMaterial = new Qt3DExtras::QPhongMaterial(); torusMaterial->setDiffuse(QColor(QRgb(0xbeb32b))); //! [2] // Torus //! [3] m_torusEntity = new Qt3DCore::QEntity(m_rootEntity); m_torusEntity->addComponent(m_torus); m_torusEntity->addComponent(torusMaterial); m_torusEntity->addComponent(torusTransform); //! [3] // Cone shape data Qt3DExtras::QConeMesh *cone = new Qt3DExtras::QConeMesh(); cone->setTopRadius(0.5); cone->setBottomRadius(1); cone->setLength(3); cone->setRings(50); cone->setSlices(20); // ConeMesh Transform Qt3DCore::QTransform *coneTransform = new Qt3DCore::QTransform(); coneTransform->setScale(1.5f); coneTransform->setRotation(QQuaternion::fromAxisAndAngle(QVector3D(1.0f, 0.0f, 0.0f), 45.0f)); coneTransform->setTranslation(QVector3D(0.0f, 4.0f, -1.5)); Qt3DExtras::QPhongMaterial *coneMaterial = new Qt3DExtras::QPhongMaterial(); coneMaterial->setDiffuse(QColor(QRgb(0x928327))); // Cone m_coneEntity = new Qt3DCore::QEntity(m_rootEntity); m_coneEntity->addComponent(cone); m_coneEntity->addComponent(coneMaterial); m_coneEntity->addComponent(coneTransform); // Cylinder shape data Qt3DExtras::QCylinderMesh *cylinder = new Qt3DExtras::QCylinderMesh(); cylinder->setRadius(1); cylinder->setLength(3); cylinder->setRings(100); cylinder->setSlices(20); // CylinderMesh Transform Qt3DCore::QTransform *cylinderTransform = new Qt3DCore::QTransform(); cylinderTransform->setScale(1.5f); cylinderTransform->setRotation(QQuaternion::fromAxisAndAngle(QVector3D(1.0f, 0.0f, 0.0f), 45.0f)); cylinderTransform->setTranslation(QVector3D(-5.0f, 4.0f, -1.5)); Qt3DExtras::QPhongMaterial *cylinderMaterial = new Qt3DExtras::QPhongMaterial(); cylinderMaterial->setDiffuse(QColor(QRgb(0x928327))); // Cylinder m_cylinderEntity = new Qt3DCore::QEntity(m_rootEntity); m_cylinderEntity->addComponent(cylinder); m_cylinderEntity->addComponent(cylinderMaterial); m_cylinderEntity->addComponent(cylinderTransform); // Cuboid shape data Qt3DExtras::QCuboidMesh *cuboid = new Qt3DExtras::QCuboidMesh(); // CuboidMesh Transform Qt3DCore::QTransform *cuboidTransform = new Qt3DCore::QTransform(); cuboidTransform->setScale(4.0f); cuboidTransform->setTranslation(QVector3D(5.0f, -4.0f, 0.0f)); Qt3DExtras::QPhongMaterial *cuboidMaterial = new Qt3DExtras::QPhongMaterial(); cuboidMaterial->setDiffuse(QColor(QRgb(0x665423))); //Cuboid m_cuboidEntity = new Qt3DCore::QEntity(m_rootEntity); m_cuboidEntity->addComponent(cuboid); m_cuboidEntity->addComponent(cuboidMaterial); m_cuboidEntity->addComponent(cuboidTransform); // Plane shape data Qt3DExtras::QPlaneMesh *planeMesh = new Qt3DExtras::QPlaneMesh(); planeMesh->setWidth(2); planeMesh->setHeight(2); // Plane mesh transform Qt3DCore::QTransform *planeTransform = new Qt3DCore::QTransform(); planeTransform->setScale(1.3f); planeTransform->setRotation(QQuaternion::fromAxisAndAngle(QVector3D(1.0f, 0.0f, 0.0f), 45.0f)); planeTransform->setTranslation(QVector3D(0.0f, -4.0f, 0.0f)); Qt3DExtras::QPhongMaterial *planeMaterial = new Qt3DExtras::QPhongMaterial(); planeMaterial->setDiffuse(QColor(QRgb(0xa69929))); // Plane m_planeEntity = new Qt3DCore::QEntity(m_rootEntity); m_planeEntity->addComponent(planeMesh); m_planeEntity->addComponent(planeMaterial); m_planeEntity->addComponent(planeTransform); // Sphere shape data Qt3DExtras::QSphereMesh *sphereMesh = new Qt3DExtras::QSphereMesh(); sphereMesh->setRings(20); sphereMesh->setSlices(20); sphereMesh->setRadius(2); // Sphere mesh transform Qt3DCore::QTransform *sphereTransform = new Qt3DCore::QTransform(); sphereTransform->setScale(1.3f); sphereTransform->setTranslation(QVector3D(-5.0f, -4.0f, 0.0f)); Qt3DExtras::QPhongMaterial *sphereMaterial = new Qt3DExtras::QPhongMaterial(); sphereMaterial->setDiffuse(QColor(QRgb(0xa69929))); // Sphere m_sphereEntity = new Qt3DCore::QEntity(m_rootEntity); m_sphereEntity->addComponent(sphereMesh); m_sphereEntity->addComponent(sphereMaterial); m_sphereEntity->addComponent(sphereTransform); }
Qgs3DMapScene::Qgs3DMapScene( const Qgs3DMapSettings &map, Qt3DExtras::QForwardRenderer *defaultFrameGraph, Qt3DRender::QRenderSettings *renderSettings, Qt3DRender::QCamera *camera, const QRect &viewportRect, Qt3DCore::QNode *parent ) : Qt3DCore::QEntity( parent ) , mMap( map ) , mForwardRenderer( defaultFrameGraph ) { 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. //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) renderSettings->pickingSettings()->setPickMethod( Qt3DRender::QPickingSettings::TrianglePicking ); #endif // Camera float aspectRatio = ( float )viewportRect.width() / viewportRect.height(); camera->lens()->setPerspectiveProjection( 45.0f, 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( camera ); mCameraController->resetView( 1000 ); // create terrain entity createTerrain(); 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 ); // 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 ); Qt3DCore::QEntity *lightEntity = new Qt3DCore::QEntity; Qt3DCore::QTransform *lightTransform = new Qt3DCore::QTransform; lightTransform->setTranslation( QVector3D( 0, 1000, 0 ) ); // defaults: white, intensity 0.5 // attenuation: constant 1.0, linear 0.0, quadratic 0.0 Qt3DRender::QPointLight *light = new Qt3DRender::QPointLight; light->setConstantAttenuation( 0 ); //light->setColor(Qt::white); //light->setIntensity(0.5); lightEntity->addComponent( light ); lightEntity->addComponent( lightTransform ); lightEntity->setParent( this ); #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 defaultFrameGraph->setFrustumCullingEnabled( false ); } // force initial update of chunked entities onCameraChanged(); }