RingProfile.cs 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  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 along the perimeter of a circle with controllable radiation patterns.
  9. /// </summary>
  10. /// <remarks>
  11. /// <para>
  12. /// The <see cref="RingProfile"/> positions new particles exclusively on the circumference of a circle centered
  13. /// at the emitter's position. Unlike <see cref="CircleProfile"/> which distributes particles throughout the
  14. /// circular area, this profile places particles only on the edge.
  15. /// </para>
  16. /// <para>
  17. /// The movement direction (heading) of each particle can be configured to radiate inward toward the center,
  18. /// outward from the center, or in random directions unrelated to their position.
  19. /// </para>
  20. /// </remarks>
  21. public sealed class RingProfile : Profile
  22. {
  23. /// <summary>
  24. /// The radius if the ring.
  25. /// </summary>
  26. public float Radius;
  27. /// <summary>
  28. /// The radiation mode that determines how particle headings are calculated.
  29. /// </summary>
  30. public CircleRadiation Radiate;
  31. /// <summary>
  32. /// Computes the offset and heading for a new particle.
  33. /// </summary>
  34. /// <param name="offset">A pointer to the Vector2 where the offset from the emitter position will be stored.</param>
  35. /// <param name="heading">A pointer to the Vector2 where the unit direction vector will be stored.</param>
  36. /// <exception cref="ArgumentOutOfRangeException">
  37. /// Thrown when <see cref="Radiate"/> contains an unsupported value.
  38. /// </exception>
  39. public override unsafe void GetOffsetAndHeading(Vector2* offset, Vector2* heading)
  40. {
  41. FastRandom.Shared.NextUnitVector(heading);
  42. switch (Radiate)
  43. {
  44. case CircleRadiation.In:
  45. offset->X = -heading->X * Radius;
  46. offset->Y = -heading->Y * Radius;
  47. break;
  48. case CircleRadiation.Out:
  49. offset->X = heading->X * Radius;
  50. offset->Y = heading->Y * Radius;
  51. break;
  52. case CircleRadiation.None:
  53. offset->X = heading->X * Radius;
  54. offset->Y = heading->Y * Radius;
  55. FastRandom.Shared.NextUnitVector(heading);
  56. break;
  57. default:
  58. throw new ArgumentOutOfRangeException(nameof(Radiate), Radiate, "Unsupported radiation mode");
  59. }
  60. }
  61. }