UiParticleEmitterComponent.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #pragma once
  9. #include <LyShine/Bus/UiCanvasBus.h>
  10. #include <LyShine/Bus/UiParticleEmitterBus.h>
  11. #include <LyShine/Bus/UiInitializationBus.h>
  12. #include <LyShine/Bus/UiElementBus.h>
  13. #include <LyShine/Bus/UiRenderBus.h>
  14. #include <LyShine/Bus/UiCanvasUpdateNotificationBus.h>
  15. #include <LyShine/Bus/UiVisualBus.h>
  16. #include <LyShine/Bus/UiIndexableImageBus.h>
  17. #include <LyShine/UiComponentTypes.h>
  18. #include <LyShine/IRenderGraph.h>
  19. #include <AzCore/Component/Component.h>
  20. #include <AzCore/Math/Color.h>
  21. #include <AzCore/Math/Random.h>
  22. #include <LmbrCentral/Rendering/TextureAsset.h>
  23. #include <Particle/UiParticle.h>
  24. ////////////////////////////////////////////////////////////////////////////////////////////////////
  25. class UiParticleEmitterComponent
  26. : public AZ::Component
  27. , public UiCanvasSizeNotificationBus::Handler
  28. , public UiParticleEmitterBus::Handler
  29. , public UiInitializationBus::Handler
  30. , public UiRenderBus::Handler
  31. , public UiCanvasUpdateNotificationBus::Handler
  32. , public UiElementNotificationBus::Handler
  33. , public UiVisualBus::Handler
  34. , public UiIndexableImageBus::Handler
  35. {
  36. public: // member functions
  37. AZ_COMPONENT(UiParticleEmitterComponent, LyShine::UiParticleEmitterComponentUuid, AZ::Component);
  38. UiParticleEmitterComponent();
  39. ~UiParticleEmitterComponent() override;
  40. // UiCanvasSizeNotificationInterface
  41. void OnCanvasSizeOrScaleChange(AZ::EntityId canvasEntityId) override;
  42. // ~UiCanvasSizeNotificationBusInterface
  43. // UiParticleEmitterInterface
  44. bool GetIsEmitting() override;
  45. void SetIsEmitting(bool emitParticles) override;
  46. bool GetIsRandomSeedFixed() override;
  47. void SetIsRandomSeedFixed(bool randomSeedFixed) override;
  48. int GetRandomSeed() override;
  49. void SetRandomSeed(int randomSeed) override;
  50. bool GetIsParticlePositionRelativeToEmitter() override;
  51. void SetIsParticlePositionRelativeToEmitter(bool relativeToEmitter) override;
  52. float GetParticleEmitRate() override;
  53. void SetParticleEmitRate(float particleEmitRate) override;
  54. bool GetIsEmitOnActivate() override;
  55. void SetIsEmitOnActivate(bool emitOnActivate) override;
  56. bool GetIsHitParticleCountOnActivate() override;
  57. void SetIsHitParticleCountOnActivate(bool hitParticleCountOnActivate) override;
  58. bool GetIsEmitterLifetimeInfinite() override;
  59. void SetIsEmitterLifetimeInfinite(bool emitterLifetimeInfinite) override;
  60. float GetEmitterLifetime() override;
  61. void SetEmitterLifetime(float emitterLifetime) override;
  62. bool GetIsParticleCountLimited() override;
  63. void SetIsParticleCountLimited(bool particleCountLimited) override;
  64. AZ::u32 GetMaxParticles() override;
  65. void SetMaxParticles(AZ::u32 maxParticles) override;
  66. EmitShape GetEmitterShape() override;
  67. void SetEmitterShape(EmitShape emitterShape) override;
  68. bool GetIsEmitOnEdge() override;
  69. void SetIsEmitOnEdge(bool emitOnEdge) override;
  70. float GetInsideEmitDistance() override;
  71. void SetInsideEmitDistance(float insideEmitDistance) override;
  72. float GetOutsideEmitDistance() override;
  73. void SetOutsideEmitDistance(float outsideEmitDistance) override;
  74. ParticleInitialDirectionType GetParticleInitialDirectionType() override;
  75. void SetParticleInitialDirectionType(ParticleInitialDirectionType initialDirectionType) override;
  76. float GetEmitAngle() override;
  77. void SetEmitAngle(float emitAngle) override;
  78. float GetEmitAngleVariation() override;
  79. void SetEmitAngleVariation(float emitAngleVariation) override;
  80. bool GetIsParticleLifetimeInfinite() override;
  81. void SetIsParticleLifetimeInfinite(bool infiniteLifetime) override;
  82. float GetParticleLifetime() override;
  83. void SetParticleLifetime(float lifetime) override;
  84. float GetParticleLifetimeVariation() override;
  85. void SetParticleLifetimeVariation(float lifetimeVariation) override;
  86. ISprite* GetSprite() override;
  87. void SetSprite(ISprite* sprite) override;
  88. AZStd::string GetSpritePathname() override;
  89. void SetSpritePathname(AZStd::string spritePath) override;
  90. bool GetIsSpriteSheetAnimated() override;
  91. void SetIsSpriteSheetAnimated(bool isSpriteSheetAnimated) override;
  92. bool GetIsSpriteSheetAnimationLooped() override;
  93. void SetIsSpriteSheetAnimationLooped(bool isSpriteSheetAnimationLooped) override;
  94. bool GetIsSpriteSheetIndexRandom() override;
  95. void SetIsSpriteSheetIndexRandom(bool isSpriteSheetIndexRandom) override;
  96. int GetSpriteSheetCellIndex() override;
  97. void SetSpriteSheetCellIndex(int spriteSheetIndex) override;
  98. int GetSpriteSheetCellEndIndex() override;
  99. void SetSpriteSheetCellEndIndex(int spriteSheetEndIndex) override;
  100. float GetSpriteSheetFrameDelay() override;
  101. void SetSpriteSheetFrameDelay(float spriteSheetFrameDelay) override;
  102. bool GetIsParticleAspectRatioLocked() override;
  103. void SetIsParticleAspectRatioLocked(bool aspectRatioLocked) override;
  104. AZ::Vector2 GetParticlePivot() override;
  105. void SetParticlePivot(AZ::Vector2 particlePivot) override;
  106. AZ::Vector2 GetParticleSize() override;
  107. void SetParticleSize(AZ::Vector2 particleSize) override;
  108. float GetParticleWidth() override;
  109. void SetParticleWidth(float width) override;
  110. float GetParticleWidthVariation() override;
  111. void SetParticleWidthVariation(float widthVariation) override;
  112. float GetParticleHeight() override;
  113. void SetParticleHeight(float height) override;
  114. float GetParticleHeightVariation() override;
  115. void SetParticleHeightVariation(float heightVariation) override;
  116. ParticleCoordinateType GetParticleMovementCoordinateType() override;
  117. void SetParticleMovementCoordinateType(ParticleCoordinateType particleVelocityMovement) override;
  118. ParticleCoordinateType GetParticleAccelerationCoordinateType() override;
  119. void SetParticleAccelerationCoordinateType(ParticleCoordinateType particleAccelerationMovement) override;
  120. AZ::Vector2 GetParticleInitialVelocity() override;
  121. void SetParticleInitialVelocity(AZ::Vector2 initialVelocity) override;
  122. AZ::Vector2 GetParticleInitialVelocityVariation() override;
  123. void SetParticleInitialVelocityVariation(AZ::Vector2 initialVelocityVariation) override;
  124. float GetParticleSpeed() override;
  125. void SetParticleSpeed(float speed) override;
  126. float GetParticleSpeedVariation() override;
  127. void SetParticleSpeedVariation(float speedVariation) override;
  128. AZ::Vector2 GetParticleAcceleration() override;
  129. void SetParticleAcceleration(AZ::Vector2 acceleration) override;
  130. bool GetIsParticleRotationFromVelocity() override;
  131. void SetIsParticleRotationFromVelocity(bool rotationFromVelocity) override;
  132. bool GetIsParticleInitialRotationFromInitialVelocity() override;
  133. void SetIsParticleInitialRotationFromInitialVelocity(bool rotationFromVelocity) override;
  134. float GetParticleInitialRotation() override;
  135. void SetParticleInitialRotation(float initialRotation) override;
  136. float GetParticleInitialRotationVariation() override;
  137. void SetParticleInitialRotationVariation(float initialRotationVariation) override;
  138. float GetParticleRotationSpeed() override;
  139. void SetParticleRotationSpeed(float rotationSpeed) override;
  140. float GetParticleRotationSpeedVariation() override;
  141. void SetParticleRotationSpeedVariation(float rotationSpeedVariation) override;
  142. AZ::Color GetParticleColor() override;
  143. void SetParticleColor(AZ::Color color) override;
  144. float GetParticleColorBrightnessVariation() override;
  145. void SetParticleColorBrightnessVariation(float brightnessVariation) override;
  146. float GetParticleColorTintVariation() override;
  147. void SetParticleColorTintVariation(float tintVariation) override;
  148. float GetParticleAlpha() override;
  149. void SetParticleAlpha(float alpha) override;
  150. // ~UiParticleEmitterInterface
  151. // UiInitializationInterface
  152. void InGamePostActivate() override;
  153. // ~UiInitializationInterface
  154. // UiRenderInterface
  155. void Render(LyShine::IRenderGraph* renderGraph) override;
  156. // ~UiRenderInterface
  157. // UiCanvasUpdateNotification
  158. void Update(float deltaTime) override;
  159. // ~UiCanvasUpdateNotification
  160. // UiElementNotifications
  161. void OnUiElementFixup(AZ::EntityId canvasEntityId, AZ::EntityId parentEntityId) override;
  162. void OnUiElementAndAncestorsEnabledChanged(bool areElementAndAncestorsEnabled) override;
  163. // ~UiElementNotifications
  164. // UiVisualInterface
  165. void ResetOverrides() override;
  166. void SetOverrideColor(const AZ::Color& color) override;
  167. void SetOverrideAlpha(float alpha) override;
  168. // ~UiVisualInterface
  169. // UiIndexableImageBus
  170. void SetImageIndex(AZ::u32 index) override;
  171. const AZ::u32 GetImageIndex() override;
  172. const AZ::u32 GetImageIndexCount() override;
  173. AZStd::string GetImageIndexAlias(AZ::u32 index) override;
  174. void SetImageIndexAlias(AZ::u32 index, const AZStd::string& alias) override;
  175. AZ::u32 GetImageIndexFromAlias(const AZStd::string& alias) override;
  176. // ~UiIndexableImageBus
  177. public: // static member functions
  178. static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
  179. {
  180. provided.push_back(AZ_CRC("UiParticleEmitterService"));
  181. provided.push_back(AZ_CRC("UiVisualService", 0xa864fdf8));
  182. }
  183. static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required)
  184. {
  185. required.push_back(AZ_CRC("UiTransformService", 0x3a838e34));
  186. }
  187. static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
  188. {
  189. incompatible.push_back(AZ_CRC("UiVisualService", 0xa864fdf8));
  190. }
  191. static void Reflect(AZ::ReflectContext* context);
  192. protected: // member functions
  193. // AZ::Component
  194. void Init() override;
  195. void Activate() override;
  196. void Deactivate() override;
  197. // ~AZ::Component
  198. void ClearActiveParticles();
  199. AZ::Vector3 GetRandomParticlePosition();
  200. AZ::Vector2 GetRandomParticleVelocity(const AZ::Vector2& particlePosition, const AZ::Vector2& emitterPosition);
  201. float GetRandomParticleRotation(const AZ::Vector2& initialVelocity, const AZ::Vector2& initialPosition);
  202. void CreateMultiplierCurve(C2DSplineTrack& curve, const AZStd::vector<ParticleFloatKeyframe>& pointList);
  203. void CreateMultiplierCurve(UiCompoundSplineTrack& curve, const AZStd::vector<ParticleColorKeyframe>& pointList);
  204. int GetCurveIndividualTangentFlags(ParticleKeyframeTangentType tangent);
  205. void SetCurveKeyTangentFlags(int& flags, ParticleKeyframeTangentType inTangent, ParticleKeyframeTangentType outTangent);
  206. void SortMultipliersByTime(AZStd::vector<ParticleFloatKeyframe>& pointList);
  207. void ResetParticleBuffers();
  208. bool IsEmitterLifetimeFinite();
  209. bool IsParticleLifetimeFinite();
  210. bool IsParticleLimitRequired();
  211. bool IsParticleLimitToggleable();
  212. bool IsEmitAngleRequired();
  213. bool CanEmitFromCenter();
  214. bool IsInitialRotationRequired();
  215. bool IsRotationRequired();
  216. bool IsEmitFromGivenAngle();
  217. bool IsShapeWithEdge();
  218. bool IsEmittingFromEdge();
  219. const char* GetSpriteSheetIndexPropertyLabel();
  220. const char* GetParticleWidthMultiplierPropertyLabel();
  221. const char* GetParticleWidthMultiplierPropertyDescription();
  222. bool IsSpriteTypeSpriteSheet();
  223. bool IsSpriteSheetCellRangeRequired();
  224. bool IsMovementCoordinateTypeCartesian();
  225. bool IsMovementCoordinateTypePolar();
  226. bool IsAspectRatioUnlocked();
  227. void CheckMaxParticleValidity();
  228. void OnSpritePathnameChange();
  229. void OnSpriteSheetCellIndexChanged();
  230. void OnSpriteSheetCellEndIndexChanged();
  231. void OnParticleSizeChange();
  232. void OnSizeXMultiplierChange();
  233. void OnSizeYMultiplierChange();
  234. void OnSpeedMultiplierChange();
  235. void OnColorMultiplierChange();
  236. void OnAlphaMultiplierChange();
  237. using AZu32ComboBoxVec = AZStd::vector<AZStd::pair<AZ::u32, AZStd::string> >;
  238. AZu32ComboBoxVec PopulateSpriteSheetIndexStringList();
  239. //! Mark the render graph as dirty, this should be done when any change is made affects the structure of the graph
  240. void MarkRenderGraphDirty();
  241. protected: // data
  242. AZ_DISABLE_COPY_MOVE(UiParticleEmitterComponent);
  243. static const AZ::u32 m_activeParticlesLimit;
  244. static const float m_emitRateLimit;
  245. bool m_isRandomSeedFixed = false;
  246. int m_randomSeed = 0;
  247. bool m_isPositionRelativeToEmitter = false;
  248. float m_emitRate = 300.0f;
  249. bool m_isEmitOnActivate = true;
  250. bool m_isHitParticleCountOnActivate = false;
  251. bool m_isEmitterLifetimeInfinite = true;
  252. float m_emitterLifetime = 1.0f;
  253. bool m_isParticleCountLimited = false;
  254. AZ::u32 m_maxParticles = 100;
  255. EmitShape m_emitShape = EmitShape::Point;
  256. bool m_isEmitOnEdge = false;
  257. float m_insideDistance = 0.0f;
  258. float m_outsideDistance = 0.0f;
  259. float m_emitAngle = 0.0f;
  260. float m_emitAngleVariation = 180.0f;
  261. bool m_isParticleLifetimeInfinite = false;
  262. float m_particleLifetime = 2.0f;
  263. float m_particleLifetimeVariation = 0.5f;
  264. AzFramework::SimpleAssetReference<LmbrCentral::TextureAsset> m_spritePathname;
  265. bool m_isSpriteSheetAnimated = false;
  266. bool m_isSpriteSheetAnimationLooped = true;
  267. bool m_isSpriteSheetIndexRandom = false;
  268. AZ::u32 m_spriteSheetCellIndex = 0;
  269. AZ::u32 m_spriteSheetCellEndIndex = 0;
  270. float m_spriteSheetFrameDelay = 0.0f;
  271. LyShine::BlendMode m_blendMode = LyShine::BlendMode::Normal;
  272. ISprite* m_sprite = nullptr;
  273. bool m_isParticleAspectRatioLocked = true;
  274. AZ::Vector2 m_particlePivot = AZ::Vector2(0.5f, 0.5f);
  275. AZ::Vector2 m_particleSize = AZ::Vector2(5.0f, 5.0f);
  276. AZ::Vector2 m_particleSizeVariation = AZ::Vector2(0.0f, 0.0f);
  277. AZStd::vector<ParticleFloatKeyframe> m_particleWidthMultiplier;
  278. AZStd::vector<ParticleFloatKeyframe> m_particleHeightMultiplier;
  279. C2DSplineTrack m_particleWidthMultiplierCurve;
  280. C2DSplineTrack m_particleHeightMultiplierCurve;
  281. ParticleCoordinateType m_particleMovementCoordinateType = ParticleCoordinateType::Cartesian;
  282. ParticleCoordinateType m_particleAccelerationCoordinateType = ParticleCoordinateType::Cartesian;
  283. // Initial velocity for Polar movement
  284. AZ::Vector2 m_particleInitialVelocity = AZ::Vector2(0.0f, 0.0f);
  285. AZ::Vector2 m_particleInitialVelocityVariation = AZ::Vector2(0.0f, 0.0f);
  286. // Initial speed for Cartesian movement
  287. float m_particleSpeed = 45.0f;
  288. float m_particleSpeedVariation = 30.0f;
  289. ParticleInitialDirectionType m_particleInitialDirectionType = ParticleInitialDirectionType::RelativeToEmitAngle; // used with Cartesian movement to calculate direction
  290. AZ::Vector2 m_particleAcceleration = AZ::Vector2(0.0f, 40.0f);
  291. bool m_isParticleRotationFromVelocity = false;
  292. bool m_isParticleInitialRotationFromInitialVelocity = false;
  293. float m_particleInitialRotation = 0.0f;
  294. float m_particleInitialRotationVariation = 0.0f;
  295. float m_particleRotationSpeed = 0.0f;
  296. float m_particleRotationSpeedVariation = 0.0f;
  297. AZStd::vector<ParticleFloatKeyframe> m_particleSpeedMultiplier;
  298. C2DSplineTrack m_particleSpeedMultiplierCurve;
  299. AZ::Color m_particleColor = AZ::Color(1.0f, 1.0f, 1.0f, 1.0f); // alpha is ignored
  300. float m_particleColorBrightnessVariation = 0.0f;
  301. float m_particleColorTintVariation = 0.0f;
  302. AZStd::vector<ParticleColorKeyframe> m_particleColorMultiplier;
  303. UiCompoundSplineTrack m_particleColorMultiplierCurve;
  304. float m_particleAlpha = 1.0f; // alpha separated as it's more likely to be animated
  305. AZStd::vector<ParticleFloatKeyframe> m_particleAlphaMultiplier;
  306. C2DSplineTrack m_particleAlphaMultiplierCurve;
  307. bool m_isColorOverridden = false;
  308. bool m_isAlphaOverridden = false;
  309. AZ::Color m_overrideColor = AZ::Color(1.0f, 1.0f, 1.0f, 1.0f);
  310. float m_overrideAlpha = 1.0f;
  311. float m_emitterAge = 0.0f;
  312. float m_nextEmitTime = 0.0f;
  313. bool m_isEmitting = false;
  314. float m_currentAspectRatio = 1.0f;
  315. AZ::Vector2 m_currentParticleSize = AZ::Vector2(5.0f, 5.0f);
  316. AZ::SimpleLcgRandom m_random;
  317. AZStd::vector<UiParticle> m_particleContainer;
  318. AZ::u32 m_particleBufferSize = 0;
  319. LyShine::UiPrimitive m_cachedPrimitive;
  320. };