LineProfile.cs 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. // Copyright (c) Craftwork Games. All rights reserved.
  2. // Licensed under the MIT license.
  3. // See LICENSE file in the project root for full license information.
  4. using System;
  5. using Microsoft.Xna.Framework;
  6. namespace MonoGame.Extended.Particles.Profiles;
  7. /// <summary>
  8. /// A profile that distributes particles uniformly along a line segment with random headings.
  9. /// </summary>
  10. /// <remarks>
  11. /// The <see cref="LineProfile"/> positions particles randomly along a line segment centered at the emitter position and
  12. /// defined by an axis direction and length.
  13. /// </remarks>
  14. public sealed class LineProfile : Profile
  15. {
  16. /// <summary>
  17. /// The direction vector of the line axis.
  18. /// </summary>
  19. public Vector2 Axis;
  20. /// <summary>
  21. /// The length of the line segment.
  22. /// </summary>
  23. public float Length;
  24. /// <summary>
  25. /// The emission direction vector used when <see cref="Radiate"/> is <see cref="LineRadiation.Directional"/>
  26. /// or as a scale factor when <see cref="Radiate"/> is <see cref="LineRadiation.NormalUp"/> or <see cref="LineRadiation.NormalDown"/>.
  27. /// </summary>
  28. /// <remarks>
  29. /// For <see cref="LineRadiation.Directional"/>, this vector directly specifies the particle heading direction.
  30. /// For <see cref="LineRadiation.NormalUp"/> and <see cref="LineRadiation.NormalDown"/>, this vector's magnitude and sign
  31. /// control the normal emission behavior. Positive values emit in the specified normal direction, while negative values
  32. /// flip to the opposite direction.
  33. /// This property is ignored when <see cref="Radiate"/> is <see cref="LineRadiation.None"/>.
  34. /// </remarks>
  35. public Vector2 Direction = Vector2.UnitY;
  36. /// <summary>
  37. /// The radiation mode that determines how particle headings are calculated.
  38. /// </summary>
  39. public LineRadiation Radiate = LineRadiation.None;
  40. /// <summary>
  41. /// Computes the offset and heading for a new particle.
  42. /// </summary>
  43. /// <param name="offset">A pointer to the Vector2 where the offset from the emitter position will be stored.</param>
  44. /// <param name="heading">A pointer to the Vector2 where the unit direction vector will be stored.</param>
  45. /// <exception cref="InvalidOperationException">
  46. /// Thrown when <see cref="Radiate"/> contains an unsupported value.
  47. /// </exception>
  48. public override unsafe void GetOffsetAndHeading(Vector2* offset, Vector2* heading)
  49. {
  50. float value = FastRandom.Shared.NextSingle(Length * -0.5f, Length * 0.5f);
  51. offset->X = Axis.X * value;
  52. offset->Y = Axis.Y * value;
  53. // Calculate heading based on radiation mode
  54. switch (Radiate)
  55. {
  56. case LineRadiation.None:
  57. FastRandom.Shared.NextUnitVector(heading);
  58. break;
  59. case LineRadiation.Directional:
  60. Vector2 normalizedDirection = Vector2.Normalize(Direction);
  61. heading->X = normalizedDirection.X;
  62. heading->Y = normalizedDirection.Y;
  63. break;
  64. case LineRadiation.PerpendicularUp:
  65. Vector2 normalizedAxisUp = Vector2.Normalize(Axis);
  66. heading->X = normalizedAxisUp.Y;
  67. heading->Y = -normalizedAxisUp.X;
  68. break;
  69. case LineRadiation.PerpendicularDown:
  70. Vector2 normalizedAxisDown = Vector2.Normalize(Axis);
  71. heading->X = -normalizedAxisDown.Y;
  72. heading->Y = normalizedAxisDown.X;
  73. break;
  74. default:
  75. throw new InvalidOperationException($"Unsupported radiation mode '{Radiate}'");
  76. }
  77. }
  78. }