On Sat, 16 Apr 2011, Anders Gidenstam wrote:
I think that is a different leak from the effects. IIRC each particle
system is attached to the scene graph in (at least) two places: at the
emitter's location in the graph and in a global vector of particle system
updaters. IIRC they are never removed from the global list of updaters
(a bug - but a hard one to fix due to concurrency issues).
Tim knows more about this.
My failed attempt to unlink the particle systems might provide some
insight into that issue. The attempt is broken because the
methods calls
if (!Particles::getCommonRoot()->removeChild(item)) {
or
if (!Particles::getCommonGeode()->removeDrawable(item)) {
can get called while another OSG thread traverses or inserts into the
vector of children to the common root/geod.
Basically the ~CustomMatrixTransform() destructor is called on the wrong
thread for this attempt to work. The clean up action needs either to be
communicated to the right thread or synchronization added to
removeChild/Drawable() method (which would be against the OSG design).
(Note: the preprocessor variable OSG_PARTICLE_FIX is unrelated to my
changes.)
Cheers,
Anders
--
---------------------------------------------------------------------------
Anders Gidenstam
WWW: http://www.gidenstam.org/FlightGear/
diff --git a/simgear/scene/model/particles.cxx b/simgear/scene/model/particles.cxx
index acac7df..4d49ac3 100644
--- a/simgear/scene/model/particles.cxx
+++ b/simgear/scene/model/particles.cxx
@@ -51,6 +51,57 @@
namespace simgear
{
+
+class CustomMatrixTransform : public osg::MatrixTransform
+{
+public:
+ CustomMatrixTransform(osgParticle::ParticleSystem* particleSystem) :
+ item(0) {
+ this->particleSystem = particleSystem;
+ };
+
+#ifdef OSG_PARTICLE_FIX
+ void setCleanupItem(osg::Group* item)
+#else
+ void setCleanupItem(osg::Drawable* item)
+#endif
+ {
+ this->item = item;
+ }
+
+protected:
+ ~CustomMatrixTransform()
+ {
+ if (!Particles::getPSU()->removeParticleSystem(particleSystem)) {
+ SG_LOG(SG_GENERAL, SG_ALERT,
+ "particles.cxx: ~CustomMatrixTransform() "
+ "Cleanup of particle system updater failed" << std::endl);
+ }
+ if (item) {
+#ifdef OSG_PARTICLE_FIX
+ if (!Particles::getCommonRoot()->removeChild(item)) {
+ SG_LOG(SG_GENERAL, SG_ALERT,
+ "particles.cxx: ~CustomMatrixTransform() "
+ "Cleanup of common root failed" << std::endl);
+ }
+#else
+ if (!Particles::getCommonGeode()->removeDrawable(item)) {
+ SG_LOG(SG_GENERAL, SG_ALERT,
+ "particles.cxx: ~CustomMatrixTransform() "
+ "Cleanup of common geode failed" << std::endl);
+ }
+#endif
+ }
+ }
+
+ osg::ref_ptr<osgParticle::ParticleSystem> particleSystem;
+#ifdef OSG_PARTICLE_FIX
+ osg::ref_ptr<osg::Group> item;
+#else
+ osg::ref_ptr<osg::Drawable> item;
+#endif
+};
+
void GlobalParticleCallback::operator()(osg::Node* node, osg::NodeVisitor* nv)
{
enabled = !enabledNode || enabledNode->getBoolValue();
@@ -151,7 +202,7 @@ osg::Group * Particles::appendParticles(const SGPropertyNode* configNode,
//may not be used depending on the configuration
PointerGuard<Particles> callback;
- getPSU()->addParticleSystem(particleSys);
+ getPSU()->addParticleSystem(particleSys);
getPSU()->setUpdateCallback(new GlobalParticleCallback(modelRoot));
//contains counter, placer and shooter by default
osgParticle::ModularEmitter* emitter = new osgParticle::ModularEmitter;
@@ -160,7 +211,7 @@ osg::Group * Particles::appendParticles(const SGPropertyNode* configNode,
// Set up the alignment node ("stolen" from animation.cxx)
// XXX Order of rotations is probably not correct.
- osg::MatrixTransform *align = new osg::MatrixTransform;
+ CustomMatrixTransform* align = new CustomMatrixTransform(particleSys);
osg::Matrix res_matrix;
res_matrix.makeRotate(
configNode->getFloatValue("offsets/pitch-deg", 0.0)*SG_DEGREES_TO_RADIANS,
@@ -202,8 +253,10 @@ osg::Group * Particles::appendParticles(const SGPropertyNode* configNode,
g->addDrawable(particleSys);
callback()->particleFrame->addChild(g);
getCommonRoot()->addChild(callback()->particleFrame.get());
+ align->setCleanupItem(callback()->particleFrame.get());
#else
getCommonGeode()->addDrawable(particleSys);
+ align->setCleanupItem(particleSys);
#endif
}
std::string textureFile;
------------------------------------------------------------------------------
Benefiting from Server Virtualization: Beyond Initial Workload
Consolidation -- Increasing the use of server virtualization is a top
priority.Virtualization can reduce costs, simplify management, and improve
application availability and disaster protection. Learn more about boosting
the value of server virtualization. http://p.sf.net/sfu/vmware-sfdev2dev
_______________________________________________
Flightgear-devel mailing list
Flightgear-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/flightgear-devel