public override void Update(NodeReference reference, ParticleEffectInstance instance, TimeSpan 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) { //Spawn lots of particles var dt = Math.Min(delta.TotalSeconds, 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); count++; } } } instance.ParticleCounts[reference.EmitterIndex] = count; }
public ParticleLibrary(ResourceManager res, AleFile ale) { Resources = res; foreach (var effect in ale.FxLib.Effects) { var fx = new ParticleEffect(this); fx.CRC = effect.CRC; fx.Name = effect.Name; Dictionary <uint, NodeReference> nodesByIndex = new Dictionary <uint, NodeReference>(); foreach (var noderef in effect.Fx) { FxNode node = null; if (!noderef.IsAttachmentNode) { var nd = ale.NodeLib.Nodes.FirstOrDefault((arg) => arg.CRC == noderef.CRC); if (nd == null) { node = new FxNode("error node", "error node"); FLLog.Error("Fx", fx.Name + " bad node CRC 0x" + noderef.CRC.ToString("x")); } else { node = NodeFromAle(ale.NodeLib.Nodes.Where((arg) => arg.CRC == noderef.CRC).First()); } } var reference = new NodeReference(); reference.Node = node; reference.IsAttachmentNode = noderef.IsAttachmentNode; nodesByIndex.Add(noderef.Index, reference); } foreach (var noderef in effect.Fx) { var nd = nodesByIndex[noderef.Index]; if (noderef.Parent != 32768) { var parent = nodesByIndex[noderef.Parent]; parent.Children.Add(nd); nd.Parent = parent; } } foreach (var pair in effect.Pairs) { var n1 = nodesByIndex[pair.Item1]; var n2 = nodesByIndex[pair.Item2]; n1.Paired.Add(n2); } fx.References = new List <NodeReference>(nodesByIndex.Values); Effects.Add(fx); } }
protected static Matrix4x4 GetAttachment(NodeReference reference, Matrix4x4 attachment) { if (reference.IsAttachmentNode) { return(attachment); } else if (reference.Parent == null) { return(Matrix4x4.Identity); } else { return(GetAttachment(reference.Parent, attachment)); } }
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 float GetMaxDistance(NodeReference reference) { var pr = reference; float max = 0; while (pr != null && !pr.IsAttachmentNode) { if (pr.Node.Transform.HasTransform) { max += Max3(pr.Node.Transform.TranslateX.GetMax(true), pr.Node.Transform.TranslateY.GetMax(true), pr.Node.Transform.TranslateZ.GetMax(true)); } pr = pr.Parent; } return(max); }
public override void Update(NodeReference reference, ParticleEffectInstance instance, TimeSpan delta, ref Matrix4 transform, float sparam) { if (reference.Paired.Count == 0) { 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(reference); 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, reference, instance, ref transform, sparam); var app = ((FxAppearance)instance.Particles[idx].Appearance.Node); app.OnParticleSpawned(idx, instance.Particles[idx].Appearance, instance); } } } }
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 direction = RandomInCone(instance.Random, s_min, s_max); var tr = Transform.GetMatrix(sparam, globaltime); 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 static Matrix4 GetTranslation(NodeReference reference, Matrix4 attachment, float sparam, float time) { Matrix4 mat = Matrix4.Identity; if (reference.Node != null && reference.Node.Transform != null) { mat = reference.Node.Transform.GetMatrix(sparam, time); } if (reference.IsAttachmentNode) { return(mat * attachment); } else if (reference.Parent == null) { return(mat); } else { return(mat * GetTranslation(reference.Parent, attachment, sparam, time)); } }
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; }
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( instance.Random.NextFloat(-w, w), instance.Random.NextFloat(-h, h), instance.Random.NextFloat(-d, d) ); var n = RandomInCone(instance.Random, s_min, s_max); var tr = Transform.GetMatrix(sparam, globaltime); //var tr = Matrix4.Identity; 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 Draw(ref Particle particle, float globaltime, NodeReference reference, ResourceManager res, Billboards billboards, ref Matrix4 transform, float sparam) { var time = particle.TimeAlive / particle.LifeSpan; var node_tr = GetTranslation(reference, transform, sparam, time); 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(); billboards.DrawPerspective( tex, p, new Vector2(Size.GetValue(sparam, time)), new Color4(c, a), tl, tr, bl, br, n, Rotate == null ? 0f : MathHelper.DegreesToRadians(Rotate.GetValue(sparam, time)), SortLayers.OBJECT, BlendInfo ); if (DrawNormals) { Debug.DrawLine(p - (n * 8), p + (n * 8)); } }
protected bool DoTransform(NodeReference reference, float sparam, float t1, float t2, out Vector3 translate, out Quaternion rotate) { translate = Vector3.Zero; rotate = Quaternion.Identity; int idx = -1; var pr = reference; while (pr != null && !pr.IsAttachmentNode) { if (pr.Node.Transform.HasTransform && pr.Node.Transform.Animates) { idx++; transforms[idx] = pr.Node.Transform; } pr = pr.Parent; } for (int i = idx; i >= 0; i--) { translate += transforms[i].GetDeltaTranslation(sparam, t1, t2); rotate *= transforms[i].GetDeltaRotation(sparam, t1, t2); } return(idx != -1); }
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 override void Draw(ref Particle particle, float globaltime, NodeReference reference, ResourceManager res, Billboards billboards, ref Matrix4 transform, float sparam) { var time = particle.TimeAlive / particle.LifeSpan; var node_tr = GetTranslation(reference, transform, sparam, time); var src_pos = particle.Position; var l = Length.GetValue(sparam, time); var w = Width.GetValue(sparam, time); var sc = Scale.GetValue(sparam, time); if (!CenterOnPos) { var nd = particle.Normal.Normalized(); src_pos += nd * (l * sc * 0.25f); } var p = node_tr.Transform(src_pos); 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(src_pos + (particle.Normal * 20)); var n = (p2 - p).Normalized(); billboards.DrawRectAppearance( tex, p, new Vector2(l, w) * sc * 0.5f, new Color4(c, a), tl, tr, bl, br, n, Rotate == null ? 0f : Rotate.GetValue(sparam, time), SortLayers.OBJECT, BlendInfo ); /*var p1_proj = Project(billboards, p); * var p2_proj = Project(billboards, p2); * * var px1 = new Vector2( * (p1_proj.X + 1) / 2 * 1024, * (1 - p1_proj.Y) / 2 * 768); * var px2 = new Vector2( * (p2_proj.X + 1) / 2 * 1024, * (1 - p2_proj.Y) / 2 * 1024 * ); * * var angle = (float)Math.Atan2(px2.Y - px1.Y, px2.X - px1.X);*/ /*var src_pos2 = src_pos + (particle.Normal * 20); * var angle = (float)Math.Atan2(src_pos2.Y - src_pos.Y, src_pos2.Z - src_pos.Z); * var angle_deg = MathHelper.RadiansToDegrees(angle); * billboards.Draw( * tex, * p, * new Vector2(l, w) * sc * 0.5f, * new Color4(c, a), * tl, * tr, * bl, * br, * angle, //Rotate == null ? 0f : Rotate.GetValue(sparam, time), * SortLayers.OBJECT, * BlendInfo * );*/ if (DrawNormals) { Debug.DrawLine(p - (n * 8), p + (n * 8)); } }
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; }
public override void Draw(ref Particle particle, float lasttime, float globaltime, NodeReference reference, ResourceManager res, Billboards billboards, ref Matrix4 transform, float sparam) { var time = particle.TimeAlive / particle.LifeSpan; var node_tr = GetTranslation(reference, transform, sparam, time); 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 * );*/ }
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); } }
protected virtual void SetParticle(int idx, NodeReference reference, ParticleEffectInstance instance, ref Matrix4 transform, float sparam, float globaltime) { }
public override void Draw(ref Particle particle, int pidx, float lasttime, float globaltime, NodeReference reference, ResourceManager res, ParticleEffectInstance instance, ref Matrix4x4 transform, float sparam) { var time = particle.TimeAlive / particle.LifeSpan; var node_tr = GetAttachment(reference, transform); var src_pos = particle.Position; var l = Length.GetValue(sparam, time); var w = Width.GetValue(sparam, time); var sc = Scale.GetValue(sparam, time); if (!CenterOnPos) { var nd = particle.Normal.Normalized(); src_pos += nd * (l * sc * 0.25f); } var p = Vector3.Transform(src_pos, node_tr); 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 = Vector3.Transform(src_pos + (particle.Normal * 20), node_tr); //var n = (p2 - p).Normalized(); var n = Vector3.TransformNormal(particle.Normal, transform).Normalized(); instance.Pool.DrawRect( particle.Instance, this, tex, p, new Vector2(l, w) * sc * 0.5f, new Color4(c, a), tl, tr, bl, br, n, Rotate == null ? 0f : MathHelper.DegreesToRadians(Rotate.GetValue(sparam, time)) ); if (DrawNormals) { Debug.DrawLine(p - (n * 12), p + (n * 12)); } }
public override void Draw(ref Particle particle, float lasttime, float globaltime, NodeReference reference, ResourceManager res, Billboards billboards, 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); billboards.Draw( tex, 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)), SortLayers.OBJECT, BlendInfo ); }
public virtual void Draw(ref Particle particle, float lasttime, float globaltime, NodeReference reference, ResourceManager res, Billboards billboards, ref Matrix4 transform, float sparam) { }
public virtual void Update(NodeReference reference, ParticleEffectInstance instance, double delta, ref Matrix4x4 transform, float sparam) { }
public override void Draw(ref Particle particle, float lasttime, float globaltime, NodeReference reference, ResourceManager res, Billboards billboards, 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); var n = (transform * new Vector4(particle.Normal.Normalized(), 0)).Xyz.Normalized(); billboards.DrawPerspective( 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)), SortLayers.OBJECT, BlendInfo ); if (DrawNormals) { //Debug.DrawLine(p - (n * 100), p + (n * 100)); } }
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 void SetNodeEnabled(NodeReference node, bool enabled) => enableStates[node.Index] = enabled;
public override void Draw(ref Particle particle, float lasttime, float globaltime, NodeReference reference, ResourceManager res, Billboards billboards, ref Matrix4 transform, float sparam) { var time = particle.TimeAlive / particle.LifeSpan; var node_tr = GetAttachment(reference, transform); var src_pos = particle.Position; var l = Length.GetValue(sparam, time); var w = Width.GetValue(sparam, time); var sc = Scale.GetValue(sparam, time); if (!CenterOnPos) { var nd = particle.Normal.Normalized(); src_pos += nd * (l * sc * 0.25f); } var p = node_tr.Transform(src_pos); 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(src_pos + (particle.Normal * 20)); //var n = (p2 - p).Normalized(); var n = (transform * new Vector4(particle.Normal.Normalized(), 0)).Xyz.Normalized(); billboards.DrawRectAppearance( tex, p, new Vector2(l, w) * sc * 0.5f, new Color4(c, a), tl, tr, bl, br, n, Rotate == null ? 0f : MathHelper.DegreesToRadians(Rotate.GetValue(sparam, time)), SortLayers.OBJECT, BlendInfo ); if (DrawNormals) { Debug.DrawLine(p - (n * 12), p + (n * 12)); } }
public override void Draw(ref Particle particle, float lasttime, float globaltime, NodeReference reference, ResourceManager res, Billboards billboards, ref Matrix4 transform, float sparam) { //Empty on purpose. Individual particles don't draw }