Particle engine crashing fix (for torque 1.2)
by Robert Elek · 12/08/2003 (8:54 am) · 6 comments
I've just discovered a problem in torque 1.2 - when i have a lot of particles in a mission, ending the mission crashes the engine - while removing the particle objects, the particle engine still tries to use them.
Note: this patch requires the improved particle emitters patch
You can find it here..
www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=4096
It's easier to reproduce on slow cpus or with a lot of particles.
The fix is ugly, but it works, thanks to Ben Garney for the idea.
First in particleEmitter.cc, in method ParticleEmitterNode::onRemove() add the line marked with comment (fixed)
this will clean the reference from the emitter to the node, when the node no longer exists.
the following things are not nice at all - we replace the datablock pointers with SimObjectPtr-s, so we will now, when they are no longer available.
In particleEmitter.h replace the definition of mDataBlock in class ParticleEmitterNode with
(original is like: ParticleEmitterNodeData* mDataBlock)
In particleEngine.h replace the definition of mDataBlock in class ParticleEmitter with
(original is like: ParticleEmitterData* mDataBlock)
In particleEngine.cc replace the definition of dataBlock in struct Particle with
(original is like: ParticleData* dataBlock)
And now the fix:
Still in particelEngine.cc in method PEngine::updateSingleParticle add the following check after the asserts:
It's all - now it's not crashing - at least, i can't reproduce it :)
I hope I helped you, have a great time using Torque :)
Note: this patch requires the improved particle emitters patch
You can find it here..
www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=4096
It's easier to reproduce on slow cpus or with a lot of particles.
The fix is ugly, but it works, thanks to Ben Garney for the idea.
First in particleEmitter.cc, in method ParticleEmitterNode::onRemove() add the line marked with comment (fixed)
void ParticleEmitterNode::onRemove()
{
removeFromScene();
if (isClientObject()) {
mEmitter->LinkObject = NULL; // (fixed)
mEmitter->deleteWhenEmpty();
mEmitter = NULL;
}
Parent::onRemove();
}this will clean the reference from the emitter to the node, when the node no longer exists.
the following things are not nice at all - we replace the datablock pointers with SimObjectPtr-s, so we will now, when they are no longer available.
In particleEmitter.h replace the definition of mDataBlock in class ParticleEmitterNode with
SimObjectPtr<ParticleEmitterNodeData> mDataBlock;
(original is like: ParticleEmitterNodeData* mDataBlock)
In particleEngine.h replace the definition of mDataBlock in class ParticleEmitter with
SimObjectPtr<ParticleEmitterData> mDataBlock;
(original is like: ParticleEmitterData* mDataBlock)
In particleEngine.cc replace the definition of dataBlock in struct Particle with
SimObjectPtr<ParticleData> dataBlock;
(original is like: ParticleData* dataBlock)
And now the fix:
Still in particelEngine.cc in method PEngine::updateSingleParticle add the following check after the asserts:
if (particle->dataBlock.isNull() || !emitter.getDataBlock()) return; // (fixed)
It's all - now it's not crashing - at least, i can't reproduce it :)
I hope I helped you, have a great time using Torque :)
#2
12/08/2003 (2:05 pm)
Why is this a resource and not entered into the project manager?
#4
12/08/2003 (9:21 pm)
Thnx Robert, i asked about this in the IRC, and here it is =)
#5
I get the following error when trying (Release_1_2_0):
particleEmitter.cc(144): error C2039: 'LinkObject' : is not a member of 'ParticleEmitter'
01/05/2004 (5:33 am)
Can you actually compile this code?I get the following error when trying (Release_1_2_0):
particleEmitter.cc(144): error C2039: 'LinkObject' : is not a member of 'ParticleEmitter'
#6
06/27/2007 (9:11 am)
We've also run into particle emitter crashes when going into one mission directly from another one (basically destroying the current mission, then reloading a new one). Our solution was to replace all calls of "deleteWhenEmpty()" on our used particle systems to instead be "deleteObject()". What this effectively does is make the particle emitters destroyed immediately on level quit, instead of remaining around for the next tick, while the particle datablock has already been destroyed which seems to be causing the crash as it still attempts to render the particle for another frame or so while accessing invalid data. 
Torque Owner Robert Elek
This is a quick _fix_ ...
Sorry :)