// Copyright (c) Craftwork Games. All rights reserved. // Licensed under the MIT license. // See LICENSE file in the project root for full license information. using System; using Microsoft.Xna.Framework; namespace MonoGame.Extended.Particles.Profiles; /// /// A profile that distributes particles uniformly along a line segment with random headings. /// /// /// The positions particles randomly along a line segment centered at the emitter position and /// defined by an axis direction and length. /// public sealed class LineProfile : Profile { /// /// Gets or sets the direction vector of the line axis. /// public Vector2 Axis { get; set; } /// /// Gets or sets the length of the line segment. /// public float Length { get; set; } /// /// Gets or sets the emission direction vector used when is /// or as a scale factor when is /// or . /// /// /// For , this vector directly specifies the particle heading direction. /// For and , this vector's /// magnitude and sign control the normal emission behavior. Positive values emit in the specified normal direction, /// while negative values flip to the opposite direction. /// This property is ignored when is . /// public Vector2 Direction { get; set; }= Vector2.UnitY; /// /// Gets or sets the radiation mode that determines how particle headings are calculated. /// public LineRadiation Radiate { get; set; } = LineRadiation.None; /// /// Computes the offset and heading for a new particle. /// /// A pointer to the Vector2 where the offset from the emitter position will be stored. /// A pointer to the Vector2 where the unit direction vector will be stored. /// /// Thrown when contains an unsupported value. /// public override unsafe void GetOffsetAndHeading(Vector2* offset, Vector2* heading) { float value = FastRandom.Shared.NextSingle(Length * -0.5f, Length * 0.5f); Vector2 normalizedAxis = Vector2.Normalize(Axis); offset->X = normalizedAxis.X * value; offset->Y = normalizedAxis.Y * value; // Calculate heading based on radiation mode switch (Radiate) { case LineRadiation.None: FastRandom.Shared.NextUnitVector(heading); break; case LineRadiation.Directional: Vector2 normalizedDirection = Vector2.Normalize(Direction); heading->X = normalizedDirection.X; heading->Y = normalizedDirection.Y; break; case LineRadiation.PerpendicularUp: heading->X = normalizedAxis.Y; heading->Y = -normalizedAxis.X; break; case LineRadiation.PerpendicularDown: heading->X = -normalizedAxis.Y; heading->Y = normalizedAxis.X; break; default: throw new InvalidOperationException($"Unsupported radiation mode '{Radiate}'"); } } }