Creating a particle effect from a template doesn't work [Reproducable, cause found]
by Trent · in Torque X 3D · 01/03/2010 (7:35 am) · 5 replies
I want to create a particle effect explosion during a collision handler, but it doesn't work. It seems you can't create any kind of object during an event handler.
Why would this be?
Why would this be?
About the author
#2
Binding a CreateParticleFromTemplate() method to a key press instead of instatiating it BeginRun does not work.
I added this code to Game.cs:
In BeginRun, I added simple code after sceneView.Camera = camera;
Note that the code below works and a particle effect system is displayed on the screen.
Now, I want to create a particle effect when I press a key, so I comment out the last two lines of the above code then altered FreeCameraComponent:
Added the following line to _SetupInputMap()
_inputMap.BindCommand(keyboardId, (int) Keys.Space, CreateParticleEmitter, null);
Added the following method to FreeCameraComponent:
The method CreateParticleEmitter() is called when I hit the space key (confirmed with a breakpoint) method but nothing appears, regardless of the UseFixedTimeStep setting.
Ok I think I'm finished editing this post now...
01/04/2010 (12:40 am)
I wrote a test from a fresh project to try and help me with this. So far I have found that if you set UseFixedTimeStep to true in the torqueSettings.xml file, particle effects will not show up.Binding a CreateParticleFromTemplate() method to a key press instead of instatiating it BeginRun does not work.
I added this code to Game.cs:
private TorqueObject CreateParticleTemplate()
{
var entity = new TorqueObject();
entity.Name = "exp_tmp";
entity.IsTemplate = true;
entity.PoolWithComponents = true;
var scene = new T3DSceneComponent();
scene.SceneGroup = entity.Name + "_scene";
scene.Position = new Vector3(1024, 1024 + 50, 300);
entity.Components.AddComponent(scene);
var mat = new SimpleMaterial();
mat.TextureFilename = "data/particle";
mat.SourceBlend = Blend.One;
mat.DestinationBlend = Blend.One;
mat.IsTranslucent = true;
mat.IsColorBlended = true;
var pdata = new T3DParticleData();
pdata.Material = mat;
var edata = new T3DParticleEmitterData();
edata.ParticleData = pdata;
var emitter = new T3DParticleEmitter();
emitter.ParticleEmitterData = edata;
emitter.UseLocalTransform = true;
var effect = new T3DParticleEffectComponent();
effect.SceneGroupName = scene.SceneGroup;
effect.DeleteWhenFinished = false;
effect.Emitters.Add(emitter);
entity.Components.AddComponent(effect);
TorqueObjectDatabase.Instance.Dictionary.SetValue<TorqueObject>(entity, entity.Name, null);
return entity;
}In BeginRun, I added simple code after sceneView.Camera = camera;
Note that the code below works and a particle effect system is displayed on the screen.
var pt = CreateParticleTemplate(); var p = pt.CloneT(); Assert.Fatal(TorqueObjectDatabase.Instance.Register(p), "um");
Now, I want to create a particle effect when I press a key, so I comment out the last two lines of the above code then altered FreeCameraComponent:
Added the following line to _SetupInputMap()
_inputMap.BindCommand(keyboardId, (int) Keys.Space, CreateParticleEmitter, null);
Added the following method to FreeCameraComponent:
private void CreateParticleEmitter()
{
var tmp = TorqueObjectDatabase.Instance.FindObject<TorqueObject>("exp_tmp");
var pe = tmp.CloneT();
Assert.Fatal(TorqueObjectDatabase.Instance.Register(pe), "oh no");
}The method CreateParticleEmitter() is called when I hit the space key (confirmed with a breakpoint) method but nothing appears, regardless of the UseFixedTimeStep setting.
Ok I think I'm finished editing this post now...
#3
01/04/2010 (8:54 am)
Strangely it seems that T3DParticleEmitter.HasParticles is false. A breakpoint in T3DParticleEmitter.Render() shows _numParticles == 0.
#4
The key items here are that if the particle system is created without initial particles and registered prior to startup it works fine, but in order to get it to play later on you need to give it initial particles, which is not always what you want.
Also I think there needs to be a way to choose whether to clone just the references to the emitters or clone the emitters themselves. If you clone an effect then modify the emitter, currently you modify all instances of the emitter, because well, they're all pointing at the same one. I guess you can get around this by creating new ones every time, but for particle effects I think pooling is a must have.
01/04/2010 (8:50 pm)
Ok, if you give the particle emitter some initial particles it works. However it works too good. It doesn't matter if the emitter is in a template or not, it emits particles always!The key items here are that if the particle system is created without initial particles and registered prior to startup it works fine, but in order to get it to play later on you need to give it initial particles, which is not always what you want.
Also I think there needs to be a way to choose whether to clone just the references to the emitters or clone the emitters themselves. If you clone an effect then modify the emitter, currently you modify all instances of the emitter, because well, they're all pointing at the same one. I guess you can get around this by creating new ones every time, but for particle effects I think pooling is a must have.
#5
01/04/2010 (9:35 pm)
While we're at it, it's probably bad form to loop through the ParticleData.Times array in _updateKeyData() using a constant as the loop counter (T3DParticleData.Constants.NUM_KEYS) while allowing the user to assign a new array of any length to the times, colors and sizes properties. At best the loop only uses the first NUM_KEYS (4 in this case) elements. At worst you get an array index out of bounds exception like I got.
Torque Owner Trent