sebastian.vesenmayer Posted November 14, 2018 Share Posted November 14, 2018 (edited) Hi, I try to turn on and off a object particles which I loaded by Unigine::World::get()->loadNode, but nothing happens. The code below will be visited in debug. But particles are still spawning. Unigine::Vector<Unigine::NodePtr> hierarchy; myloadednode->getHierarchy(hierarchy); for (auto & node : hierarchy) { if (node->getType() == Unigine::Node::OBJECT_PARTICLES) { Unigine::ObjectParticlesPtr particle = Unigine::ObjectParticles::cast(node); particle->setNumberPerSpawn(0); particle->setEmitterEnabled(0); } } Did I forget something? Thanks, Sebastian Edited November 14, 2018 by sebastian.vesenmayer Link to comment
fox Posted November 14, 2018 Share Posted November 14, 2018 Hi Sebastian, You can disable a node by simply calling: particle->setEnabled(0); Is it ok in your case? Thank you! Link to comment
sebastian.vesenmayer Posted November 14, 2018 Author Share Posted November 14, 2018 (edited) No, because it disables all spawned particles and does not fade out slowly. In the editor it is working, but not by c++ api. Edited November 14, 2018 by sebastian.vesenmayer Link to comment
fox Posted November 14, 2018 Share Posted November 14, 2018 So, you want to stop spawning particles and let the ones already spawned fade away... In this case disabling the emitter by calling particle->setEmitterEnabled(0); should work. Could you provide a small test sample that reproduces the issue, to identify the problem? Thank you! Link to comment
fox Posted November 15, 2018 Share Posted November 15, 2018 Hi Sebastian, I've double-checked it and everything seems to work. At least the following code (AppWorldLogic.cpp): #include <UnigineWorld.h> #include <UnigineGame.h> // ... NodePtr n; int AppWorldLogic::init() { // loading a particle system created in the UnigineEditor and exported to the my_particles.node file n = Unigine::World::get()->loadNode("my_particles.node"); // ... } // ... // some stupid flag to disable the particle system emitter only once bool flag = true; int AppWorldLogic::update() { // disabling the particle system emitter after 5 seconds if (flag && (Game::get()->getTime() > 5)) { if (n) //-----------PART OF YOUR CODE---------------------------------------------------- if (n->getType() == Unigine::Node::OBJECT_PARTICLES) { Unigine::ObjectParticlesPtr particle = Unigine::ObjectParticles::cast(n); // disabling the particle system emitter particle->setEmitterEnabled(0); flag = false; } //-------------------------------------------------------------------------------- } } works ok with a particle system created by default in the UnigineEditor and exported to a *.node file. Are you sure you're running the right version (debug or release). This might happen, for example, when you make modifications to a debug version, but launching a release one. Thanks! Link to comment
sebastian.vesenmayer Posted November 15, 2018 Author Share Posted November 15, 2018 (edited) Thank you Fox, I checked our code and it seems that we did create the node more than 1 time and lost the Pointer. The Object loaded by Unigine::World::get()->loadNode("my_particles.node"); won't get destroyed when the smart pointer goes out of scope. Edited November 15, 2018 by sebastian.vesenmayer Link to comment
sebastian.vesenmayer Posted November 15, 2018 Author Share Posted November 15, 2018 Ok, next problem, I cannot destroy the particle system. int AppWorldLogic::init() { // Write here code to be called on world initialization: initialize resources for your world scene during the world start. smokeNode = Unigine::World::get()->loadNode("Smoke/Smoke_Gray.node"); smokeNode->grab(); return 1; } // start of the main loop int AppWorldLogic::update() { // Write here code to be called before updating each render frame: specify all graphics-related functions you want to be called every frame while your application executes. smokeNode.destroy(); return 1; } It is still visible in the small example. Link to comment
fox Posted November 15, 2018 Share Posted November 15, 2018 You're welcome, Sebastian! Ok, again I'd ask for a sample, as in my case everything works as it should: #include <UnigineWorld.h> #include <UnigineGame.h> // ... NodePtr n; int AppWorldLogic::init() { // loading a particle system created in the UnigineEditor and exported to the my_particles.node file n = Unigine::World::get()->loadNode("my_particles.node"); n->grab(); // ... } // ... int AppWorldLogic::update() { // destroying the particle system after 5 seconds if (Game::get()->getTime() > 5) { if (n) n.destroy(); } } Please check this out! Thank you! Link to comment
sebastian.vesenmayer Posted November 16, 2018 Author Share Posted November 16, 2018 Hi Fox, I did but it is still there after 5 seconds. Attached my node, texture, material and the code files. Thanks particle_not_vanishing_example.zip Link to comment
fox Posted November 18, 2018 Share Posted November 18, 2018 Hi Sebastien, Now it's clear! There is a hierarchy in your *.node file with a couple of particle systems and a dummy node as a root. There is one thing about the destroy() method, that you should be aware of: you can load a large hierarchy of objects via World::get()->loadNode(), but when you delete a smart pointer of the root node of the hierarchy (e.g. by calling the destroy() method), only the node pointed by the interface will be deleted. All its children will become orphans and will remain in the world. In case of a NodeReference things are simple: as you delete it, the whole its hierachy is deleted as well, so there's nothing to worry about. In all other cases we'll have to delete all children recursively. Therefore, at run time it is recommended either to create NodeReferences or single nodes via the World's loadNode() method. Moreover, you can pass node ownership to the Editor (it always exists, even when you don't see it) and use the following: Editor::get()->addNode() - now the Editor will own the object and manage it. Don't forget to call release() for all interfaces before adding nodes to the Editor. Editor::get()->releaseNode() - release Editor ownership. Now the object can be controlled by you - just call grab() and it's yours. Editor::get()->removeNode() - deletes the node. The best thing in this case is that when the Editor is the owner it deletes the node with all its hierarchy automatically. Generally, if you need to manage (create and delete) complex node hierarchies and change worlds, the best option might be to pass ownership to the Editor, after previously calling release() for all interfaces. // ... Unigine::NodePtr smokeNode; int AppWorldLogic::init() { // ... // loading a node from a file and passing it to the Editor smokeNode = Unigine::World::get()->loadNode("Smoke/Smoke_Gray.node"); smokeNode->release(); Unigine::Editor::get()->addNode(smokeNode); return 1; } int AppWorldLogic::update() { if (Unigine::Game::get()->getTime() > 5) { if (smokeNode) { // deleting a node with all its hierarchy (second parameter of the removeNode is set to 1) and clearing a pointer Unigine::Editor::get()->removeNode(smokeNode,1); smokeNode.clear(); } } return 1; } // ... In this case, when you change worlds, no orphan nodes will remain in memory, as the Editor deletes all nodes it owns on unloading a world. Hope this helps, Sebastien! Thank you! Link to comment
sebastian.vesenmayer Posted November 19, 2018 Author Share Posted November 19, 2018 Hi fox, it works now. But does it make sense, because when I destroy a root object, shouldn't the reference counter decrement for every child object and they delete themself when they reach zero? What is the benefit to have orphans, when they are not controllable anymore? Is this mentioned in the documentation? I didn't find the hint. Thank you, Sebastian Link to comment
fox Posted November 19, 2018 Share Posted November 19, 2018 Glad to hear that, Sebastien! Unfortunately hierarchies don't work that way, a pointer to root object is just a pointer to root object and it doesn't manage all the hierarchy. There were hints in the docs here and there, but with the upcoming release a new article on working with smart pointers will be available, with this particular topic included, to make programmer's life easier. Thank you! Link to comment
Recommended Posts