bool ParticleSystem::isDead() const { for(EmitterSet::const_iterator i=emitters.begin(); i!=emitters.end(); ++i) { ParticleEmitter *emitter = *i; if(!emitter->isDead()) { return false; } } for(ParticleBuckets::const_iterator j=buckets.begin(); j!=buckets.end(); ++j) { const ParticleBatch &bucket = j->second; const ParticleSet &set = bucket.elements; for(ParticleSet::const_iterator i=set.begin(); i!=set.end(); ++i) { if(!i->isDead()) { return false; } } } return true; }
void ParticlesEditorController::RemoveParticleLayerNode(LayerParticleEditorNode* layerToRemove) { if (!layerToRemove) { return; } EmitterParticleEditorNode* emitterNode = layerToRemove->GetEmitterEditorNode(); if (!emitterNode) { return; } ParticleEmitter* emitter = emitterNode->GetParticleEmitter(); if (!emitter) { return; } // Lookup for the layer to be removed. int32 layerIndex = layerToRemove->GetLayerIndex(); if (layerIndex == -1) { return; } // Reset the selected node in case it is one to be removed. CleanupSelectedNodeIfDeleting(layerToRemove); // Remove the node from the layers list and also from the emitter. emitter->RemoveLayer(layerIndex); emitterNode->RemoveChildNode(layerToRemove); }
bool ParticlesEditorController::PerformMoveBetweenEmitters(EmitterParticleEditorNode* oldEmitterNode, EmitterParticleEditorNode* newEmitterNode, LayerParticleEditorNode* layerNodeToMove, LayerParticleEditorNode* layerNodeToInsertAbove) { ParticleEmitter* oldParentEmitter = oldEmitterNode->GetParticleEmitter(); ParticleEmitter* newParentEmitter = newEmitterNode->GetParticleEmitter(); if (!oldParentEmitter || !newParentEmitter) { return false; } // Move the Editor node. layerNodeToInsertAbove is allowed to be NULL. newEmitterNode->AddChildNodeAbove(layerNodeToMove, layerNodeToInsertAbove); oldEmitterNode->RemoveChildNode(layerNodeToMove, false); // Move the Particle Layers themselves. ParticleLayer* layerToMove = layerNodeToMove->GetLayer(); ParticleLayer* layerToInsertAbove = NULL; if (layerNodeToInsertAbove) { layerToInsertAbove = layerNodeToInsertAbove->GetLayer(); } SafeRetain(layerToMove); oldParentEmitter->RemoveLayer(layerToMove); newParentEmitter->AddLayer(layerToMove, layerToInsertAbove); SafeRelease(layerToMove); // Update the emitter. layerNodeToMove->UpdateEmitterEditorNode(newEmitterNode); return true; }
void ParticlesEditorController::AddParticleEmitterNodeToScene(Entity* emitterSceneNode) { // We are adding new Emitter to the Particle Effect node just selected. Entity* effectNode = NULL; BaseParticleEditorNode* selectedNode = GetSelectedNode(); if (selectedNode) { effectNode = selectedNode->GetRootNode(); } EffectParticleEditorNode* effectEditorNode = GetRootForParticleEffectNode(effectNode); if (effectNode && effectEditorNode) { EmitterParticleEditorNode* emitterEditorNode = new EmitterParticleEditorNode(effectNode, emitterSceneNode, QString::fromStdString(emitterSceneNode->GetName())); ParticleEmitter * emitter = GetEmitter(emitterSceneNode); if (!emitter) { return; } emitter->SetLifeTime(LIFETIME_FOR_NEW_PARTICLE_EMITTER); effectNode->AddNode(emitterSceneNode); effectEditorNode->AddChildNode(emitterEditorNode); } }
LayerParticleEditorNode* ParticlesEditorController::CloneParticleLayerNode(LayerParticleEditorNode* layerToClone) { if (!layerToClone || !layerToClone->GetLayer()) { return NULL; } EmitterParticleEditorNode* emitterNode = layerToClone->GetEmitterEditorNode(); if (!emitterNode) { return NULL; } ParticleEmitter* emitter = emitterNode->GetParticleEmitter(); if (!emitter) { return NULL; } ParticleLayer* clonedLayer = layerToClone->GetLayer()->Clone(); emitter->AddLayer(clonedLayer); LayerParticleEditorNode* clonedEditorNode = new LayerParticleEditorNode(emitterNode, clonedLayer); emitterNode->AddChildNode(clonedEditorNode); return clonedEditorNode; }
void ParticleEmitterSystem::Update(float32 timeElapsed) { uint32 size = emitters.size(); Vector<ParticleEmitter*> emittersToBeDeleted; for(uint32 i = 0; i < size; ++i) { // Yuri Coder, 2013/05/15. Visible emitters are always updated, "deferred" update // is called for invisible ones. See pls issue #DF-1140. uint32 flags = emitters[i]->GetFlags(); if ((flags & RenderObject::VISIBILITY_CRITERIA) == RenderObject::VISIBILITY_CRITERIA) { emitters[i]->Update(timeElapsed); } else { emitters[i]->DeferredUpdate(timeElapsed); } if (emitters[i]->IsToBeDeleted()) { emittersToBeDeleted.push_back(emitters[i]); } } for(Vector<ParticleEmitter*>::iterator it = emittersToBeDeleted.begin(); it != emittersToBeDeleted.end(); ++it) { ParticleEmitter* partEmitter = (*it); RenderSystem* renderSystem = partEmitter->GetRenderSystem(); renderSystem->RemoveFromRender(partEmitter); SafeRelease(partEmitter); } }
void ParticlesEditorSceneModelHelper::SynchronizeEmitterParticleEditorNode(EmitterParticleEditorNode* node) { if (!node) { return; } ParticleEmitter* emitter = node->GetParticleEmitter(); if (!emitter) { return; } int layersCountInEmitter = emitter->GetLayers().size(); int layersCountInEmitterNode = node->GetLayersCount(); if (layersCountInEmitter > 0 && layersCountInEmitterNode == 0) { // Emitter Node has no layers - need to add them. for (int32 i = 0; i < layersCountInEmitter; i ++) { // Create the new node and add it to the tree. LayerParticleEditorNode* layerNode = new LayerParticleEditorNode(node, emitter->GetLayers()[i]); node->AddNode(layerNode); } } }
void ParticleGroup::Clone( ParticleGroup *p ) { assert(p); p->m_pDevice = m_pDevice; //p->m_b2DParticle = m_b2DParticle; p->m_CoordinateSystem = m_CoordinateSystem; p->m_bRotationTexture = m_bRotationTexture; //p->m_SceneBlendType = m_SceneBlendType; p->m_fDefaultHeight = m_fDefaultHeight; p->m_fDefaultWidth = m_fDefaultWidth; p->m_CommonDirection = m_CommonDirection; p->m_CommonUp = m_CommonUp; p->SetPoolSize( m_uiPoolSize ); p->m_TextureName = m_TextureName; p->m_pTexture = m_pTexture; if(m_pTexture) { m_pTexture->AddRef(); p->m_bAnimationTexture = m_bAnimationTexture; p->m_iSide = m_iSide; p->m_iNumFrame = m_iNumFrame; p->m_fTexAnimDuration = m_fTexAnimDuration; p->m_fTexDelta = m_fTexDelta; } p->m_BillboardType = m_BillboardType; p->m_CommonUp = m_CommonUp; ParticleEmitter *pSrcEmitter = NULL; ParticleEmitter *pDestEmitter = NULL; ParticleEmitterVector::iterator iEmit = m_Emitters.begin(); for( ; iEmit != m_Emitters.end(); ++iEmit ) { pSrcEmitter = (*iEmit); // 调用p的CreateEmitter,因为内部要为每个Emitter设置父 pDestEmitter = p->CreateEmitter( pSrcEmitter->m_Type ); if(pDestEmitter) { pSrcEmitter->Clone( pDestEmitter ); p->AddEmitter(pDestEmitter); } } //ParticleAffector *pSrcAffector = NULL; //ParticleAffector *pDestAffector = NULL; //ParticleAffectorVector::iterator iAffect = m_Affectors.begin(); /*for( ; iAffect != m_Affectors.end(); ++iAffect ) { pSrcAffector = (*iAffect); pDestAffector = p->CreateAffector( pSrcAffector->m_Type ); if(pDestAffector) { pSrcAffector->Clone(pDestAffector); p->AddAffector(pDestAffector); } }*/ }
ParticleEmitter* ParticleEmitter::create(const char* textureFile, TextureBlending textureBlending, unsigned int particleCountMax) { Texture* texture = NULL; texture = Texture::create(textureFile, false); if (!texture) { GP_ERROR("Failed to create texture for particle emitter."); return NULL; } GP_ASSERT(texture->getWidth()); GP_ASSERT(texture->getHeight()); // Use default SpriteBatch material. SpriteBatch* batch = SpriteBatch::create(texture, NULL, particleCountMax); texture->release(); // batch owns the texture. GP_ASSERT(batch); ParticleEmitter* emitter = new ParticleEmitter(batch, particleCountMax); GP_ASSERT(emitter); // By default assume only one frame which uses the entire texture. emitter->setTextureBlending(textureBlending); emitter->_spriteTextureWidth = texture->getWidth(); emitter->_spriteTextureHeight = texture->getHeight(); emitter->_spriteTextureWidthRatio = 1.0f / (float)texture->getWidth(); emitter->_spriteTextureHeightRatio = 1.0f / (float)texture->getHeight(); Rectangle texCoord((float)texture->getWidth(), (float)texture->getHeight()); emitter->setSpriteFrameCoords(1, &texCoord); return emitter; }
/** If necessary defines a new particle type for the terrain emitter. Then * adjusts the location of the terrain emitter to be in synch with the * current wheel position, and defines the emission rate depending on speed, * steering, and skidding. * \param pk Particle type to use. */ void KartGFX::updateTerrain(const ParticleKind *pk) { ParticleEmitter *pe = m_all_emitters[KGFX_TERRAIN]; if(!pe) return; pe->setParticleType(pk); const btWheelInfo &wi = m_kart->getVehicle() ->getWheelInfo(2+m_wheel_toggle); Vec3 xyz = wi.m_raycastInfo.m_contactPointWS; // FIXME: the X and Z position is not always accurate. xyz.setX(xyz.getX()+ 0.06f * (m_wheel_toggle ? +1 : -1)); xyz.setZ(xyz.getZ()+0.06f); pe->setPosition(xyz); // Now compute the particle creation rate: float rate = 0; const float speed = fabsf(m_kart->getSpeed()); const float skidding = m_kart->getSkidding()->getSkidFactor(); // Only create particles when the kart is actually on ground bool on_ground = m_kart->isOnGround() && m_kart->getSkidding()->getGraphicalJumpOffset()==0; if (skidding > 1.0f && on_ground) rate = fabsf(m_kart->getControls().m_steer) > 0.8 ? skidding - 1 : 0; else if (speed >= 0.5f && on_ground) rate = speed/m_kart->getKartProperties()->getMaxSpeed(); else { pe->setCreationRateAbsolute(0); return; } // m_skidding can be > 2, and speed > maxSpeed (if powerups are used). if(rate>1.0f) rate = 1.0f; pe->setCreationRateRelative(rate); } // updateTerrain
void ParticleEmitterNode::setEmitterDataBlock(ParticleEmitterData* data) { if ( isServerObject() ) { setMaskBits( EmitterDBMask ); } else { ParticleEmitter* pEmitter = NULL; if ( data ) { // Create emitter with new datablock pEmitter = new ParticleEmitter; pEmitter->onNewDataBlock( data, false ); if( pEmitter->registerObject() == false ) { Con::warnf(ConsoleLogEntry::General, "Could not register base emitter for particle of class: %s", data->getName() ? data->getName() : data->getIdString() ); delete pEmitter; return; } } // Replace emitter if ( mEmitter ) mEmitter->deleteWhenEmpty(); mEmitter = pEmitter; } mEmitterDatablock = data; }
void CommandLoadInnerEmitterFromYaml::Execute() { BaseParticleEditorNode* selectedNode = ParticlesEditorController::Instance()->GetSelectedNode(); InnerEmitterParticleEditorNode* innerEmitterNode = dynamic_cast<InnerEmitterParticleEditorNode*>(selectedNode); if (!innerEmitterNode || !innerEmitterNode->GetInnerEmitter() ||!innerEmitterNode->GetParticleLayer()) { return; } QString projectPath = QString(EditorSettings::Instance()->GetParticlesConfigsPath().GetAbsolutePathname().c_str()); QString filePath = QFileDialog::getOpenFileName(NULL, QString("Open Particle Emitter Yaml file"), projectPath, QString("YAML File (*.yaml)")); if (filePath.isEmpty()) { return; } ParticleEmitter* innerEmitter = innerEmitterNode->GetInnerEmitter(); innerEmitter->LoadFromYaml(filePath.toStdString()); // No additional NULL check is needed here - already performed at the beginning. QFileInfo fileInfo(filePath); ParticleLayer* innerEmitterLayer = innerEmitterNode->GetParticleLayer(); innerEmitterLayer->innerEmitterPath = FilePath(fileInfo.path().toStdString(), fileInfo.fileName().toStdString()); // Perform the validation of the Yaml file loaded. String validationMessage; if (ParticlesEditorSceneDataHelper::ValidateParticleEmitter(innerEmitter, validationMessage) == false) { ShowErrorDialog(validationMessage); } QtMainWindowHandler::Instance()->RefreshSceneGraph(); }
//---------------------------------------------------------------------------- PX2::Movable *EditMap::CreateParticlesToEffect (PX2::Node *node) { ParticleEmitter *emitter = new0 ParticleEmitter(); emitter->SetName("NewParticleEmitter"); node->AttachChild(emitter); return emitter; }
void SpritePackerHelper::ReloadParticleSprites(SceneData* sceneData) { List<Entity*> particleEffects; sceneData->GetAllParticleEffects(particleEffects); for (auto it = particleEffects.begin(); it != particleEffects.end(); ++it) { Entity* curNode = (*it); ParticleEffectComponent * effectComponent = cast_if_equal<ParticleEffectComponent*>(curNode->GetComponent(Component::PARTICLE_EFFECT_COMPONENT)); if (!effectComponent) { continue; } effectComponent->Stop(); // All the children of this Scene Node must have Emitter components. int32 emittersCount = curNode->GetChildrenCount(); for (int32 i = 0; i < emittersCount; i ++) { Entity* childNode = curNode->GetChild(i); ParticleEmitter * emitter = GetEmitter(childNode); if (!emitter) { continue; } emitter->ReloadLayerSprites(); } effectComponent->Start(); } }
void ParticleScriptCompiler::compileEmitter(const ScriptNodePtr &node) { if(node->children.empty() || node->children.front()->type != SNT_WORD) return; // Create the emitter based on the first child ParticleEmitter *emitter = 0; String type = node->children.front()->token; try{ emitter = mSystem->addEmitter(type); }catch(...){ addError(CE_OBJECTALLOCATIONERROR, node->children.front()->file, node->children.front()->line, node->children.front()->column); return; } // Jump ahead now to the '{' as the emitter does not support other parameters in the header ScriptNodeList::iterator i = findNode(node->children.begin(), node->children.end(), SNT_LBRACE); if(i == node->children.end()) return; ScriptNodeList::iterator j = (*i)->children.begin(); while(j != (*i)->children.end()) { if(!processNode(j, (*i)->children.end())) { String name = (*j)->token, value = getParameterValue((*j)->children.begin(), (*j)->children.end()); if(!emitter->setParameter(name, value)) addError(CE_INVALIDPROPERTY, (*j)->file, (*j)->line, (*j)->column); ++j; } } }
void CommandSaveInnerEmitterToYaml::Execute() { BaseParticleEditorNode* selectedNode = ParticlesEditorController::Instance()->GetSelectedNode(); InnerEmitterParticleEditorNode* emitterNode = dynamic_cast<InnerEmitterParticleEditorNode*>(selectedNode); if (!emitterNode || !emitterNode->GetInnerEmitter()) { return; } ParticleEmitter * emitter = emitterNode->GetInnerEmitter(); FilePath yamlPath = emitter->GetConfigPath(); if (this->forceAskFilename || yamlPath.IsEmpty() ) { QString projectPath = QString(EditorSettings::Instance()->GetParticlesConfigsPath().GetAbsolutePathname().c_str()); QString filePath = QFileDialog::getSaveFileName(NULL, QString("Save Particle Emitter YAML file"), projectPath, QString("YAML File (*.yaml)")); if (filePath.isEmpty()) { return; } yamlPath = FilePath(filePath.toStdString()); } emitter->SaveToYaml(yamlPath); }
RESULT ParticleManager::SetEffect( IN HParticleEmitter hParticleEmitter, HEffect hEffect ) { RESULT rval = S_OK; ParticleEmitter* pParticleEmitter = GetObjectPointer( hParticleEmitter ); if (pParticleEmitter) { #ifdef DEBUG string name; EffectMan.GetName( hEffect, &name ); DEBUGMSG(ZONE_PARTICLES, "ParticleManager::SetEffect( %s, %s )", pParticleEmitter->GetName().c_str(), name.c_str()); #endif pParticleEmitter->SetEffect( hEffect ); } else { RETAILMSG(ZONE_ERROR, "ERROR: ParticleManager::SetEffect( 0x%x, 0x%x ): object not found", (UINT32)hParticleEmitter, (UINT32)hEffect); rval = E_INVALID_ARG; } Exit: return rval; }
/** Sets a new particle type to be used. Note that the memory of this * kind must be managed by the caller. * \param type The emitter type for which to set the new particle type. * \param pk The particle kind to use. */ void KartGFX::setParticleKind(const KartGFXType type, const ParticleKind *pk) { ParticleEmitter *pe = m_all_emitters[KGFX_TERRAIN]; if(!pe) return; pe->setParticleType(pk); } // setParticleKind
void WizardSkill0::HandleNodeRemoved(StringHash eventType, VariantMap& eventData) { using namespace NodeRemoved; Node* nohd = static_cast<Node*>(eventData[P_NODE].GetPtr()); if (nohd->GetName() != "meteor") { return; } Node* fire = nohd->GetChild("fire"); if (!fire) { return; } ParticleEmitter* pe = fire->GetComponent<ParticleEmitter>(); if (!pe) { return; } pe->SetEnabled(false); nohd->RemoveAllChildren(); }
// ---------------------------------------------------------------------------- TrackObjectPresentationParticles::TrackObjectPresentationParticles( const XMLNode& xml_node, scene::ISceneNode* parent) : TrackObjectPresentationSceneNode(xml_node) { m_emitter = NULL; m_lod_emitter_node = NULL; std::string path; xml_node.get("kind", &path); int clip_distance = -1; xml_node.get("clip_distance", &clip_distance); xml_node.get("conditions", &m_trigger_condition); bool auto_emit = true; xml_node.get("auto_emit", &auto_emit); m_delayed_stop = false; m_delayed_stop_time = 0.0; #ifndef SERVER_ONLY try { ParticleKind* kind = ParticleKindManager::get()->getParticles(path); if (kind == NULL) { throw std::runtime_error(path + " could not be loaded"); } ParticleEmitter* emitter = new ParticleEmitter(kind, m_init_xyz, parent); if (clip_distance > 0) { scene::ISceneManager* sm = irr_driver->getSceneManager(); scene::ISceneNode* sroot = sm->getRootSceneNode(); LODNode* lod = new LODNode("particles", !parent ? sroot : parent, sm); lod->add(clip_distance, (scene::ISceneNode*)emitter->getNode(), true); m_node = lod; m_lod_emitter_node = lod; m_emitter = emitter; } else { m_node = emitter->getNode(); m_emitter = emitter; } if (m_trigger_condition.size() > 0 || !auto_emit) { m_emitter->setCreationRateAbsolute(0.0f); } } catch (std::runtime_error& e) { Log::warn ("Track", "Could not load particles '%s'; cause :\n %s", path.c_str(), e.what()); } #endif } // TrackObjectPresentationParticles
void ParticleSystem::updateEmitters( float milliseconds ) { for(EmitterSet::const_iterator i=emitters.begin(); i!=emitters.end(); ++i) { ParticleEmitter *emitter = *i; emitter->update(milliseconds); } }
/** Defines the new position of the specified emitter. * \param type The emitter to set a new position for. * \param xyz The new position of the emitter. */ void KartGFX::setXYZ(const KartGFXType type, const Vec3 &xyz) { #ifndef SERVER_ONLY ParticleEmitter *pe = m_all_emitters[KGFX_TERRAIN]; if(!pe) return; pe->setPosition(xyz); #endif } // setXYZ
//------------------------------------------------------------------------------ void ParticleEmitterTranslator::translate(Ogre::ScriptCompiler *compiler, const Ogre::AbstractNodePtr &node) { Ogre::ObjectAbstractNode *obj = reinterpret_cast<Ogre::ObjectAbstractNode*>(node.get()); // name can't be empty because we get renderer type from it if(obj->name.empty()) { compiler->addError(Ogre::ScriptCompiler::CE_OBJECTNAMEEXPECTED, obj->file, obj->line); return; } ParticleTechnique* tech = Ogre::any_cast<ParticleTechnique*>(obj->parent->context); ParticleEmitter* emitter = tech->CreateEmitter(obj->name); if (emitter == NULL) { compiler->addError(Ogre::ScriptCompiler::CE_OBJECTALLOCATIONERROR, obj->file, obj->line); return; } Ogre::LogManager::getSingletonPtr()->logMessage("ParticleEmitterTranslator: create emitter."); for (Ogre::AbstractNodeList::iterator i = obj->children.begin(); i != obj->children.end(); ++i) { if ((*i)->type == Ogre::ANT_PROPERTY) { Ogre::PropertyAbstractNode *prop = reinterpret_cast<Ogre::PropertyAbstractNode*>((*i).get()); Ogre::String value = prop->getValue(); /* // Glob the values together for (Ogre::AbstractNodeList::iterator i = prop->values.begin(); i != prop->values.end(); ++i) { if((*i)->type == Ogre::ANT_ATOM) { if (value.empty()) { value = ((Ogre::AtomAbstractNode*)(*i).get())->value; } else { value = value + " " + ((Ogre::AtomAbstractNode*)(*i).get())->value; } } else { compiler->addError(Ogre::ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line); break; } } */ Ogre::LogManager::getSingletonPtr()->logMessage("ParticleEmitterTranslator: Set param '" + prop->name + "' to '" + value + "'."); if (!emitter->setParameter(prop->name, value)) { compiler->addError(Ogre::ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line); } } } }
ParticleEmitter* ParticleEmitter::create(Texture* texture, BlendMode blendMode, unsigned int particleCountMax) { ParticleEmitter* emitter = new ParticleEmitter(particleCountMax); GP_ASSERT(emitter); emitter->setTexture(texture, blendMode); return emitter; }
/** Sets a new particle type to be used. Note that the memory of this * kind must be managed by the caller. * \param type The emitter type for which to set the new particle type. * \param pk The particle kind to use. */ void KartGFX::setParticleKind(const KartGFXType type, const ParticleKind *pk) { #ifndef SERVER_ONLY ParticleEmitter *pe = m_all_emitters[KGFX_TERRAIN]; if(!pe) return; pe->setParticleType(pk); #endif } // setParticleKind
ParticleDescription * ParticleEditor::GetSelectedEmitterVariance() { ParticleEmitter* emitter = GetSelectedEmitter(); auto& states = emitter->GetStateVariances(); if(state_index_ < states.size()) { return &states[state_index_]; } return nullptr; }
void ParticleSystem::kill() { for(EmitterSet::const_iterator i=emitters.begin(); i!=emitters.end(); ++i) { ParticleEmitter *emitter = *i; emitter->kill(); } buckets.clear(); }
void ParticleEditor::SelectEmitterState(size_t index) { if(state_index_ == index) { return; } ParticleEmitter* emitter = GetSelectedEmitter(); state_index_ = index; state_index_ = clamp(state_index_, (size_t) 0, emitter->GetStates().size() - 1); refresh_state_ui(); }
void KingMovementAnimation::createBlasts() { ParticleSystem* pSys = mSceneMgr->createParticleSystem( nextName(), "Effects/EnergyBlast"); mParticleNode = mAnimatedNode->createChildSceneNode(); mParticleNode->translate(0, 160, 60); mParticleNode->attachObject(pSys); ParticleEmitter *emitter = pSys->getEmitter(0); pSys->setParticleQuota(emitter->getEmissionRate() * mAttackDuration); }
void ParticleEmitterPropertyControl::ReadFrom(Entity * sceneNode) { NodesPropertyControl::ReadFrom(sceneNode); ParticleEmitter * emitter = GetEmitter(sceneNode); DVASSERT(emitter); propertyList->AddSection("Particles emitter"); propertyList->AddStringProperty("Yaml path", PropertyList::PROPERTY_IS_READ_ONLY); propertyList->SetStringPropertyValue("Yaml path", emitter->GetConfigPath().GetAbsolutePathname()); }