public override void OnParticleSpawned(int idx, NodeReference reference, ParticleEffectInstance instance) { instance.BeamAppearances[reference].Push(new LinePointer() { ParticleIndex = idx, Active = true }); }
protected override void SetParticle(int idx, ParticleEffect fx, ParticleEffectInstance instance, ref Matrix4 transform, float sparam) { float w = Width.GetValue(sparam, 0) / 2; float h = Height.GetValue(sparam, 0) / 2; float d = Depth.GetValue(sparam, 0) / 2; float s_min = MathHelper.DegreesToRadians(MinSpread.GetValue(sparam, 0)); float s_max = MathHelper.DegreesToRadians(MaxSpread.GetValue(sparam, 0)); var pos = new Vector3( instance.Random.NextFloat(-w, w), instance.Random.NextFloat(-h, h), instance.Random.NextFloat(-d, d) ); //var angle = instance.Random.NextFloat(s_min, s_max); /*var n = new Vector3( * (float)(Math.Cos(angle)), * 1, * (float)(Math.Sin(angle)) * );*/ var n = RandomInCone(instance.Random, s_min, s_max); var tr = Transform.GetMatrix(sparam, 0); n = (tr * new Vector4(n.Normalized(), 0)).Xyz.Normalized(); var pr = pos; instance.Particles[idx].Position = pr; instance.Particles [idx].Normal = n * Pressure.GetValue(sparam, 0); }
public override void OnParticleSpawned(int idx, ParticleEffectInstance instance) { instance.BeamAppearances[this].Enqueue(new LinePointer() { ParticleIndex = idx, Active = true }); }
public void Update(ParticleEffectInstance instance, TimeSpan delta, ref Matrix4 transform, float sparam) { for (int i = 0; i < emitters.Count; i++) { emitters[i].Update(this, instance, delta, ref transform, sparam); } }
protected override void SetParticle(int idx, NodeReference reference, ParticleEffectInstance instance, ref Matrix4 transform, float sparam, float globaltime) { var r_min = MinRadius.GetValue(sparam, 0); var r_max = MaxRadius.GetValue(sparam, 0); var radius = instance.Random.NextFloat(r_min, r_max); var p = new Vector3( instance.Random.NextFloat(-1, 1), instance.Random.NextFloat(-1, 1), instance.Random.NextFloat(-1, 1) ); p.Normalize(); var direction = p; var tr = Transform.GetMatrix(sparam, globaltime); var n = (tr * new Vector4(direction, 0)).Xyz.Normalized(); n *= Pressure.GetValue(sparam, 0); var pr = p * radius; instance.Particles[idx].Position = pr; instance.Particles[idx].Normal = n; }
protected override void SetParticle(int idx, NodeReference reference, ParticleEffectInstance instance, ref Matrix4 transform, float sparam, float globaltime) { float w = Width.GetValue(sparam, 0) / 2; float h = Height.GetValue(sparam, 0) / 2; float d = Depth.GetValue(sparam, 0) / 2; float s_min = MathHelper.DegreesToRadians(MinSpread.GetValue(sparam, 0)); float s_max = MathHelper.DegreesToRadians(MaxSpread.GetValue(sparam, 0)); var pos = new Vector3( FxRandom.NextFloat(-w, w), FxRandom.NextFloat(-h, h), FxRandom.NextFloat(-d, d) ); var n = RandomInCone(s_min, s_max); //var tr = Transform.GetMatrix(sparam, globaltime); //var tr = Matrix4.Identity; //n = (tr * new Vector4(n.Normalized(), 0)).Xyz.Normalized(); Vector3 translate; Quaternion rotate; if (DoTransform(reference, sparam, globaltime, out translate, out rotate)) { pos += translate; n = rotate * n; } var pr = pos; instance.Pool.Particles[idx].Position = pr; instance.Pool.Particles [idx].Normal = n * Pressure.GetValue(sparam, 0); }
protected override void SetParticle(int idx, NodeReference reference, ParticleEffectInstance instance, ref Matrix4x4 transform, float sparam, float globaltime) { var r_min = MinRadius.GetValue(sparam, 0); var r_max = MaxRadius.GetValue(sparam, 0); var radius = FxRandom.NextFloat(r_min, r_max); var p = new Vector3( FxRandom.NextFloat(-1, 1), FxRandom.NextFloat(-1, 1), FxRandom.NextFloat(-1, 1) ); p.Normalize(); var n = p; Vector3 translate; Quaternion rotate; if (DoTransform(reference, sparam, globaltime, out translate, out rotate)) { p += translate; n = Vector3.Transform(n, rotate); } n *= Pressure.GetValue(sparam, 0); var pr = p * radius; instance.Pool.Particles[idx].Position = pr; instance.Pool.Particles[idx].Normal = n; }
public override void Update(NodeReference reference, ParticleEffectInstance instance, TimeSpan delta, ref Matrix4 transform, float sparam) { if (reference.Paired.Count == 0) { return; } if (NodeLifeSpan < instance.GlobalTime) { return; } if (reference.Paired[0].Node.NodeLifeSpan < instance.GlobalTime) { return; } var maxCount = 1000; //var maxCount = MaxParticles == null ? int.MaxValue : (int)Math.Ceiling(MaxParticles.GetValue(sparam, 0f)); var freq = Frequency == null ? 0f : Frequency.GetValue(sparam, 0f); var spawnMs = freq <= 0 ? 0 : 1 / (double)freq; var state = instance.GetEmitterState(reference); if (state.ParticleCount >= maxCount) { return; } int j = 0; if (spawnMs > 0) { //Spawn lots of particles var dt = Math.Min(delta.TotalSeconds, 1); //don't go crazy during debug pauses while (true) { if (state.SpawnTimer < dt) { dt -= state.SpawnTimer; state.SpawnTimer = spawnMs; } else { state.SpawnTimer -= dt; break; } if (state.ParticleCount + 1 <= maxCount) { var idx = instance.GetNextFreeParticle(); if (idx == -1) { return; } j++; state.ParticleCount++; SpawnParticle(idx, reference, instance, ref transform, sparam, (float)instance.GlobalTime); var app = (FxAppearance)reference.Paired[0].Node; app.OnParticleSpawned(idx, instance.Pool.Particles[idx].Appearance, instance); } } } }
protected void SpawnParticle(int idx, ParticleEffect fx, ParticleEffectInstance instance, ref Matrix4 transform, float sparam) { instance.Particles[idx].Active = true; instance.Particles[idx].Emitter = this; instance.Particles[idx].Appearance = (FxAppearance)fx.Pairs[this][0]; instance.Particles[idx].TimeAlive = 0f; instance.Particles[idx].LifeSpan = InitLifeSpan.GetValue(sparam, 0f); SetParticle(idx, fx, instance, ref transform, sparam); }
protected void SpawnParticle(int idx, NodeReference reference, ParticleEffectInstance instance, ref Matrix4 transform, float sparam) { instance.Particles[idx].Active = true; instance.Particles[idx].Emitter = reference; instance.Particles[idx].Appearance = reference.Paired[0]; instance.Particles[idx].TimeAlive = 0f; instance.Particles[idx].LifeSpan = InitLifeSpan.GetValue(sparam, 0f); SetParticle(idx, reference, instance, ref transform, sparam); }
public void SpawnInitialParticles(NodeReference reference, ParticleEffectInstance instance, ref Matrix4x4 transform, float sparam) { int j = 0; for (int i = 0; i < InitialParticles; i--) { var idx = instance.GetNextFreeParticle(); if (idx == -1) { break; } SpawnParticle(idx, reference, instance, ref transform, sparam, 0); j++; } }
public void KillAll(ParticleEffectInstance instance) { for (int i = 0; i < Particles.Length; i++) { if (!Particles[i].Active) { continue; } if (Particles[i].Instance == instance) { Particles[i].Active = false; Particles[i].Instance = null; FreeParticles.Enqueue(i); } } }
public void SpawnInitialParticles(ParticleEffect fx, ParticleEffectInstance instance, ref Matrix4 transform, float sparam) { int j = 0; for (int i = 0; i < InitialParticles; i--) { var idx = instance.GetNextFreeParticle(); if (idx == -1) { break; } SpawnParticle(idx, fx, instance, ref transform, sparam); j++; } instance.GetEmitterState(this).ParticleCount = j; }
public void KillAll(ParticleEffectInstance instance) { for (int i = 0; i < Particles.Length; i++) { if (!Particles[i].Active) { continue; } if (Particles[i].Instance == instance) { Particles[i].Active = false; Particles[i].Instance.ParticleCounts[Particles[i].Emitter.EmitterIndex]--; Particles[i].Instance = null; FreeParticles.Push(i); } } }
public override void Update(ParticleEffect fx, ParticleEffectInstance instance, TimeSpan delta, ref Matrix4 transform, float sparam) { if (!fx.Pairs.ContainsKey(this)) { return; } var maxCount = MaxParticles == null ? int.MaxValue : (int)Math.Ceiling(MaxParticles.GetValue(sparam, 0f)); var freq = Frequency == null ? 0f : Frequency.GetValue(sparam, 0f); var spawnMs = freq <= 0 ? 0 : 1 / (double)freq; var state = instance.GetEmitterState(this); if (state.ParticleCount >= maxCount) { return; } if (spawnMs > 0) { //Spawn lots of particles var dt = Math.Min(delta.TotalSeconds, 1); //don't go crazy during debug pauses while (true) { if (state.SpawnTimer < dt) { dt -= state.SpawnTimer; state.SpawnTimer = spawnMs; } else { state.SpawnTimer -= dt; break; } if (state.ParticleCount + 1 <= maxCount) { var idx = instance.GetNextFreeParticle(); if (idx == -1) { return; } state.ParticleCount++; SpawnParticle(idx, fx, instance, ref transform, sparam); instance.Particles[idx].Appearance.OnParticleSpawned(idx, instance); } } } }
protected override void SetParticle(int idx, ParticleEffect fx, ParticleEffectInstance instance, ref Matrix4 transform, float sparam) { var r_min = MinRadius.GetValue(sparam, 0); var r_max = MaxRadius.GetValue(sparam, 0); var radius = instance.Random.NextFloat(r_min, r_max); float s_min = MathHelper.DegreesToRadians(MinSpread.GetValue(sparam, 0)); float s_max = MathHelper.DegreesToRadians(MaxSpread.GetValue(sparam, 0)); var direction = RandomInCone(instance.Random, s_min, s_max); var tr = Transform.GetMatrix(sparam, 0); var n = (tr * new Vector4(direction.Normalized(), 0)).Xyz.Normalized(); var p = n * radius; n *= Pressure.GetValue(sparam, 0); instance.Particles[idx].Position = p; instance.Particles[idx].Normal = n; }
protected void SpawnParticle(int idx, NodeReference reference, ParticleEffectInstance instance, ref Matrix4 transform, float sparam, float globaltime) { instance.Particles[idx].Active = true; instance.Particles[idx].Emitter = reference; instance.Particles[idx].Appearance = reference.Paired[0]; instance.Particles[idx].TimeAlive = 0f; instance.Particles[idx].LifeSpan = InitLifeSpan.GetValue(sparam, 0f); instance.Particles[idx].Orientation = Quaternion.Identity; SetParticle(idx, reference, instance, ref transform, sparam, globaltime); if (reference.Paired[0].Parent == null) { instance.Particles[idx].Position = VectorMath.Transform( instance.Particles[idx].Position, transform); var len = instance.Particles[idx].Normal.Length; var nr = instance.Particles[idx].Normal.Normalized(); var transformed = (transform * new Vector4(nr, 0)).Xyz.Normalized(); instance.Particles[idx].Normal = transformed * len; } }
protected override void SetParticle(int idx, NodeReference reference, ParticleEffectInstance instance, ref Matrix4 transform, float sparam, float globaltime) { var r_min = MinRadius.GetValue(sparam, 0); var r_max = MaxRadius.GetValue(sparam, 0); var radius = instance.Random.NextFloat(r_min, r_max); float s_min = MathHelper.DegreesToRadians(MinSpread.GetValue(sparam, 0)); float s_max = MathHelper.DegreesToRadians(MaxSpread.GetValue(sparam, 0)); var n = RandomInCone(instance.Random, s_min, s_max); Vector3 translate; Quaternion rotate; if (DoTransform(reference, sparam, globaltime, out translate, out rotate)) { n = rotate * n; } var p = n * radius + translate; n *= Pressure.GetValue(sparam, 0); instance.Particles[idx].Position = p; instance.Particles[idx].Normal = n; }
public override void Draw(ref Particle particle, int pidx, float lasttime, float globaltime, NodeReference reference, ResourceManager res, ParticleEffectInstance instance, ref Matrix4 transform, float sparam) { var time = particle.TimeAlive / particle.LifeSpan; var node_tr = GetAttachment(reference, transform); Texture2D tex; Vector2 tl, tr, bl, br; HandleTexture(res, globaltime, sparam, ref particle, out tex, out tl, out tr, out bl, out br); var c = Color.GetValue(sparam, time); var a = Alpha.GetValue(sparam, time); var q = particle.Orientation * Transform.GetDeltaRotation(sparam, lasttime, globaltime); particle.Orientation = q; var mat = Matrix4.CreateFromQuaternion(q); //TODO: why doesn't this work? //var n = (transform * new Vector4(particle.Normal.Normalized(), 0)).Xyz.Normalized(); var p = VectorMath.Transform(particle.Position, transform); var p2 = VectorMath.Transform(particle.Position + particle.Normal, transform); var n = (p - p2).Normalized(); instance.Pool.DrawPerspective( particle.Instance, this, tex, VectorMath.Transform(particle.Position, transform), mat, new Vector2(Size.GetValue(sparam, time)), new Color4(c, a), tl, tr, bl, br, n, Rotate == null ? 0f : MathHelper.DegreesToRadians(Rotate.GetValue(sparam, time)) ); if (DrawNormals) { Debug.DrawLine(p - (n * 100), p + (n * 100)); } }
public virtual void OnParticleSpawned(int idx, NodeReference reference, ParticleEffectInstance instance) { }
public virtual void Draw(ref Particle particle, int pidx, float lasttime, float globaltime, NodeReference reference, ResourceManager res, ParticleEffectInstance instance, ref Matrix4 transform, float sparam) { }
public void DrawBeamApp(PolylineRender poly, float globalTime, NodeReference reference, ParticleEffectInstance instance, ref Matrix4x4 transform, float sparam) { //get particles! var beam = instance.Beams[reference.BeamIndex]; if (beam.ParticleCount < 2) { beam.ParticleCount = 0; return; } AgeComparer.Instance.Particles = instance.Pool.Particles; Array.Sort(beam.ParticleIndices, 0, beam.ParticleCount, AgeComparer.Instance); //draw var node_tr = GetAttachment(reference, transform); Texture2D tex; Vector2 tl, tr, bl, br; var res = instance.Resources; TextureHandler.Update(Texture, res); var frame = GetFrame(globalTime, sparam, ref instance.Pool.Particles[beam.ParticleIndices[0]]); int index = (int) Math.Floor((TextureHandler.FrameCount - 1) * frame) * 4; tl = TextureHandler.Coordinates[index]; tr = TextureHandler.Coordinates[index + 1]; bl = TextureHandler.Coordinates[index + 2]; br = TextureHandler.Coordinates[index + 3]; //Sorting hack kinda var z = RenderHelpers.GetZ(instance.Pool.Camera.Position, Vector3.Transform(Vector3.Zero, node_tr)); for (int j = 0; j < 2; j++) //two planes { poly.StartLine(TextureHandler.Texture ?? res.WhiteTexture, BlendInfo); bool odd = true; Vector3 dir = Vector3.Zero; for (int i = 0; i < beam.ParticleCount; i++) { var pos = Vector3.Transform(instance.Pool.Particles[beam.ParticleIndices[i]].Position, node_tr); if (i + 1 < beam.ParticleCount) { var pos2 = Vector3.Transform(instance.Pool.Particles[beam.ParticleIndices[i + 1]].Position, node_tr); var forward = (pos2 - pos).Normalized(); var toCamera = (instance.Pool.Camera.Position - pos).Normalized(); var up = Vector3.Cross(toCamera, forward); up.Normalize(); dir = up; if (j == 1) { //Broken? Doesn't show up var right = Vector3.Cross(up, forward).Normalized(); dir = right; } } var time = instance.Pool.Particles[beam.ParticleIndices[i]].TimeAlive / instance.Pool.Particles[beam.ParticleIndices[i]].LifeSpan; var w = Width.GetValue(sparam, time); poly.AddPoint( pos + (dir * w / 2), pos - (dir * w / 2), odd ? tl : bl, odd ? tr : br, new Color4( Color.GetValue(sparam, time), Alpha.GetValue(sparam, time) ) ); odd = !odd; } poly.FinishLine(z); } beam.ParticleCount = 0; }
public override void Draw(ref Particle particle, int pidx, float lasttime, float globaltime, NodeReference reference, ResourceManager res, ParticleEffectInstance instance, ref Matrix4x4 transform, float sparam) { //Transform and add Vector3 deltap; Quaternion deltaq; if (DoTransform(reference, sparam, lasttime, globaltime, out deltap, out deltaq)) { particle.Position += deltap; particle.Orientation *= deltaq; } var beam = instance.Beams[reference.BeamIndex]; if (beam.ParticleCount >= BeamParticles.MAX_PARTICLES) return; beam.ParticleIndices[beam.ParticleCount++] = pidx; }
protected virtual void SetParticle(int idx, NodeReference reference, ParticleEffectInstance instance, ref Matrix4 transform, float sparam, float globaltime) { }
public virtual void OnParticleSpawned(int idx, ParticleEffectInstance instance) { }
public virtual void Update(ParticleEffect fx, ParticleEffectInstance instance, TimeSpan delta, ref Matrix4 transform, float sparam) { }
public override void Update(NodeReference reference, ParticleEffectInstance instance, double delta, ref Matrix4x4 transform, float sparam) { if (reference.Paired.Count == 0) { return; } if (NodeLifeSpan < instance.GlobalTime) { return; } //if (reference.Paired[0].Node.NodeLifeSpan < instance.GlobalTime) return; var maxCount = MaxParticles == null ? int.MaxValue : (int)Math.Ceiling(MaxParticles.GetValue(sparam, (float)instance.GlobalTime)); var freq = Frequency == null ? 0f : Frequency.GetValue(sparam, (float)instance.GlobalTime); var spawnMs = freq <= 0 ? 0 : 1 / (double)freq; int j = 0; var count = instance.ParticleCounts[reference.EmitterIndex]; if (spawnMs > 0) { if (instance.SpawnTimers[reference.EmitterIndex] > spawnMs) { instance.SpawnTimers[reference.EmitterIndex] = spawnMs; } //Spawn lots of particles var dt = Math.Min(delta, 1); //don't go crazy during debug pauses while (true) { if (instance.SpawnTimers[reference.EmitterIndex] < dt) { dt -= instance.SpawnTimers[reference.EmitterIndex]; instance.SpawnTimers[reference.EmitterIndex] = spawnMs; } else { instance.SpawnTimers[reference.EmitterIndex] -= dt; break; } if (count < maxCount) { var idx = instance.GetNextFreeParticle(); if (idx == -1) { return; } j++; SpawnParticle(idx, reference, instance, ref transform, sparam, (float)instance.GlobalTime); var app = (FxAppearance)reference.Paired[0].Node; app.OnParticleSpawned(idx, instance.Pool.Particles[idx].Appearance, instance); //Simulate time already alive (TODO fix the time loop properly) instance.Pool.Particles[idx].TimeAlive = (float)dt; instance.Pool.Particles[idx].Position += instance.Pool.Particles[idx].Normal * (float)dt; count++; } } } else { instance.SpawnTimers[reference.EmitterIndex] = 0; } instance.ParticleCounts[reference.EmitterIndex] = count; }
public override void Draw(ref Particle particle, int pidx, float lasttime, float globaltime, NodeReference reference, ResourceManager res, ParticleEffectInstance instance, ref Matrix4 transform, float sparam) { var time = particle.TimeAlive / particle.LifeSpan; var node_tr = GetAttachment(reference, transform); Vector3 deltap; Quaternion deltaq; if (DoTransform(reference, sparam, lasttime, globaltime, out deltap, out deltaq)) { particle.Position += deltap; particle.Orientation *= deltaq; } var p = node_tr.Transform(particle.Orientation * particle.Position); Texture2D tex; Vector2 tl, tr, bl, br; HandleTexture(res, sparam, globaltime, ref particle, out tex, out tl, out tr, out bl, out br); var c = Color.GetValue(sparam, time); var a = Alpha.GetValue(sparam, time); instance.Pool.DrawBasic( particle.Instance, this, p, new Vector2(Size.GetValue(sparam, time)) * 2, new Color4(c, a), tl, tr, bl, br, Rotate == null ? 0f : MathHelper.DegreesToRadians(Rotate.GetValue(sparam, time)) ); }
public unsafe void DrawBeamApp(PolylineRender poly, LineBuffer points, float globalTime, NodeReference reference, ParticleEffectInstance instance, ResourceManager res, Billboards billboards, ref Matrix4 transform, float sparam) { //TODO: Cross-plane not showing //TODO: In some cases particles are going backwards? (Broken emitter or LineBuffer) //TODO: See if z sorting can be better for Polyline //TODO: Implement FLBeamAppearance properties if (points.Count() < 2) { return; } //Get only active indices, alloc on stack for 0 GC pressure //int* indices = stackalloc int[512]; var indices = new int[512]; var particles = new Particle[512]; for (int i = 0; i < 512; i++) { indices[i] = -1; } int ptCount = 0; for (int i = 0; i < points.Count(); i++) { if (points[i].Active) { indices[ptCount++] = points[i].ParticleIndex; } } if (ptCount < 2) { return; } for (int i = 0; i < ptCount; i++) { particles[i] = instance.Particles[indices[i]]; } for (int i = 1; i < ptCount; i++) { if (particles[i - 1].TimeAlive > particles[i].TimeAlive) { Console.WriteLine("bad order"); } } var node_tr = GetAttachment(reference, transform); Texture2D tex; Vector2 tl, tr, bl, br; HandleTexture(res, globalTime, sparam, ref instance.Particles[indices[0]], out tex, out tl, out tr, out bl, out br); //Sorting hack kinda var z = RenderHelpers.GetZ(billboards.Camera.Position, node_tr.Transform(Vector3.Zero)); for (int j = 0; j < 2; j++) //two planes { poly.StartLine(tex, BlendInfo); bool odd = true; Vector3 dir = Vector3.Zero; for (int i = 0; i < ptCount; i++) { var pos = node_tr.Transform(instance.Particles[indices[i]].Position); if (i + 1 < ptCount) { var pos2 = node_tr.Transform(instance.Particles[indices[i + 1]].Position); var forward = (pos2 - pos).Normalized(); var toCamera = (billboards.Camera.Position - pos).Normalized(); var up = Vector3.Cross(toCamera, forward); up.Normalize(); dir = up; if (j == 1) { //Broken? Doesn't show up var right = Vector3.Cross(up, forward).Normalized(); dir = right; } } var time = instance.Particles[indices[i]].TimeAlive / instance.Particles[indices[i]].LifeSpan; var w = Width.GetValue(sparam, time); poly.AddPoint( pos + (dir * w / 2), pos - (dir * w / 2), odd ? tl : bl, odd ? tr : br, new Color4( Color.GetValue(sparam, time), Alpha.GetValue(sparam, time) ) ); odd = !odd; } poly.FinishLine(z); } }
public override void Draw(ref Particle particle, int pidx, float lasttime, float globaltime, NodeReference reference, ResourceManager res, ParticleEffectInstance instance, ref Matrix4 transform, float sparam) { var time = particle.TimeAlive / particle.LifeSpan; var node_tr = GetAttachment(reference, transform); var p = node_tr.Transform(particle.Position); Texture2D tex; Vector2 tl, tr, bl, br; HandleTexture(res, globaltime, sparam, ref particle, out tex, out tl, out tr, out bl, out br); var c = Color.GetValue(sparam, time); var a = Alpha.GetValue(sparam, time); var p2 = node_tr.Transform(particle.Position + particle.Normal); //var n = (p - p2).Normalized(); var n = Vector3.UnitZ; /*billboards.DrawPerspective( * tex, * p, * new Vector2(Width.GetValue(sparam, time), Height.GetValue(sparam, time)), * new Color4(c, a), * tl, * tr, * bl, * br, * n, * Rotate == null ? 0f : MathHelper.DegreesToRadians(Rotate.GetValue(sparam, time)), * SortLayers.OBJECT, * BlendInfo * );*/ }