Game Development Community

Bug: Particles are not safedeleting properly (TGB 1.1 release)

by Fenrir Wolf · in Torque Game Builder · 06/29/2006 (2:01 pm) · 5 replies

Repro: Create a sceneobject of any type, mount a particle effect to it. Set mount parameters to "Owned by Mount" and then delete the parent.

Observed: The particle effect immediately deletes itself, including all particles in existance.

Expected: The particles should continue to exist until aged out and then the effect and emitters are deleted from the scenegraph.

Proposed fix:

t2dParticleEffect.cc, t2dParticleEffect::playEffect (line ~3251)

// Play Effect.
bool t2dParticleEffect::playEffect( bool resetParticles )
{
	// DAVIDG
	// First of all, we're being deleted, so go away!
	// Why do we need this?  Because merging scenegraph causes playEffect events to fire.
	// If this wasn't here, our particles would continuously reset whenever something was added to this scenegraph.
	// There is PROBABLY a bug somewhere, as I really don't think this event should be called when there's another
	// scenegraph hanging around like that, even if it is being merged.
	if (isBeingDeleted())
		return false ;

   // Cannot do anything if we've not got any emitters!
   if ( mParticleEmitterList.size() == 0 )

t2dSceneGraph.cc, t2dSceneGraph::renderView (line ~3251)
// Fetch more direct reference.
                    t2dSceneObject* pSceneObject2D = (*itr);

                    // Is the Object being Deleted?
						  if ( (!pSceneObject2D->isBeingDeleted() ? 1 : !pSceneObject2D->getSafeDelete() ) ) // DAVIDG
                    {
                        // No, so is the object in view or always scoped?

t2dSceneContainer.cc, t2dSceneContainer::findObjects (line ~1043)

// Increase Bin Searches.
        mpParentSceneGraph2D->getDebugStats().objectBinSearches++;

        // Is the Object Not being ignored, Enabled, Picking (Allowed/Used) and we've got Visibility?
		  if ( pSceneObjectRef != pIgnoreObject && pSceneObjectRef->getEnabled() && (!pSceneObjectRef->isBeingDeleted() ? 1 : !pSceneObjectRef->getSafeDelete()) && ((picking && pSceneObjectRef->getIsPickingAllowed())||!picking) && (pSceneObjectRef->getVisible() || showInvisible) ) // DAVIDG
        {
            // Yes, so have we dealt with this object already?

#1
06/29/2006 (11:26 pm)
Or you could just set your particles not to be owned by mount, then check for mounted particles in your onRemove callback and do stopEffect(true,true). That will wait for particles to finish and then delete the effect entirely.
#2
06/29/2006 (11:28 pm)
Also, it's good that a particle effect is deleted instantly when it's mount is deleted IMO. Immagine the case of an object that's far off screen. Assuming the particles don't reach the camera view, you wouldnt want to wait for the system to finish before deleting it.
#3
06/30/2006 (3:13 am)
Well, the converse could be said; Just stopEffect () and tell it not to wait on the objects' onRemove event.

I'm going off the C++ code, which DOES call the C++ equiv of stopEffect(true, true) whenever the effect is deleted from a mount, but this does not work properly in the scenegraph container management. That is what my fix enables.

I disagree on the second point. Particles are always-rendered, as likely devoting CPU to bounds/view-checking for all particles outweighs potiential cycles gained. I would like to know my effects are always rendered out till the last particle and not worry about their scope or even the state of their emitter (ie: it's been orphaned and waiting to be deleted), as in most cases objects are going to remain onscreen most of the timeand fly off the screen and the be de-rezzed immediately.
#4
06/30/2006 (7:27 am)
I reported this bug (without a fix, though) ;) a while back, too. Nobody loves me.

So, thanks for the fix! :)
#5
06/30/2006 (9:33 am)
Jason, I totally missed that -- and I thought I had scoured the forums pretty good looking for issues about safeDelete/particles!

Anyway, you are welcome. :)