summaryrefslogtreecommitdiff
path: root/Runtime/Graphics/ParticleSystem/ParticleSystem.h
diff options
context:
space:
mode:
authorchai <chaifix@163.com>2019-08-14 22:50:43 +0800
committerchai <chaifix@163.com>2019-08-14 22:50:43 +0800
commit15740faf9fe9fe4be08965098bbf2947e096aeeb (patch)
treea730ec236656cc8cab5b13f088adfaed6bb218fb /Runtime/Graphics/ParticleSystem/ParticleSystem.h
+Unity Runtime codeHEADmaster
Diffstat (limited to 'Runtime/Graphics/ParticleSystem/ParticleSystem.h')
-rw-r--r--Runtime/Graphics/ParticleSystem/ParticleSystem.h298
1 files changed, 298 insertions, 0 deletions
diff --git a/Runtime/Graphics/ParticleSystem/ParticleSystem.h b/Runtime/Graphics/ParticleSystem/ParticleSystem.h
new file mode 100644
index 0000000..10c8f2a
--- /dev/null
+++ b/Runtime/Graphics/ParticleSystem/ParticleSystem.h
@@ -0,0 +1,298 @@
+#ifndef SHURIKEN_H
+#define SHURIKEN_H
+
+#include "Runtime/BaseClasses/GameObject.h"
+#include "ParticleSystemParticle.h"
+#include "Runtime/Utilities/LinkedList.h"
+#include "Modules/InitialModule.h"
+#include "Modules/ShapeModule.h"
+#include "Modules/EmissionModule.h"
+
+struct ParticleSystemEmitReplay;
+struct ParticleSystemState;
+class ParticleSystemModule;
+class SizeModule;
+class RotationModule;
+class ColorModule;
+class UVModule;
+class VelocityModule;
+class ForceModule;
+class ExternalForcesModule;
+class ClampVelocityModule;
+class SizeBySpeedModule;
+class RotationBySpeedModule;
+class ColorBySpeedModule;
+class CollisionModule;
+class SubModule;
+
+enum ParticleSystemSimulationSpace {
+ kSimLocal = 0,
+ kSimWorld = 1,
+};
+
+// TODO: rename
+struct ParticleSystemThreadScratchPad
+{
+ ParticleSystemThreadScratchPad ()
+ : deltaTime (1.0f)
+ {}
+
+ float deltaTime;
+};
+
+enum { kGoodQualityDelay = 0, kMediumQualityDelay = 0, kLowQualityDelay = 4 };
+struct RayBudgetState
+{
+ void SetQuality(int quality)
+ {
+ if ( m_Quality != quality )
+ {
+ switch (quality)
+ {
+ case 0:
+ m_QualityFrameDelay = kGoodQualityDelay;
+ break;
+ case 1:
+ m_QualityFrameDelay = kMediumQualityDelay;
+ break;
+ case 2:
+ m_QualityFrameDelay = kLowQualityDelay;
+ break;
+ default:
+ m_QualityFrameDelay = kGoodQualityDelay;
+ }
+ m_FramesRemaining = m_QualityFrameDelay;
+ m_Quality = quality;
+ };
+ }
+ RayBudgetState() { m_Quality=m_QualityFrameDelay=m_FramesRemaining=0; }
+ bool ReceiveRays() const { return m_FramesRemaining==0; }
+ void Update() { m_FramesRemaining = ( m_FramesRemaining ? m_FramesRemaining-1 : m_QualityFrameDelay ); }
+ int m_Quality;
+ int m_QualityFrameDelay;
+ int m_FramesRemaining;
+};
+
+class ParticleSystem : public Unity::Component
+{
+public:
+ REGISTER_DERIVED_CLASS (ParticleSystem, Unity::Component)
+ DECLARE_OBJECT_SERIALIZE (ParticleSystem)
+
+ enum
+ {
+ kParticleBuffer0,
+#if UNITY_EDITOR // Double buffered + interpolation
+ kParticleBuffer1,
+#endif
+ kNumParticleBuffers,
+ };
+
+ ParticleSystem (MemLabelId label, ObjectCreationMode mode);
+
+ // ParticleSystem (); declared-by-macro
+
+ void SmartReset ();
+ void AddParticleSystemRenderer ();
+
+ void Deactivate (DeactivateOperation operation);
+ void AwakeFromLoad (AwakeFromLoadMode awakeMode);
+
+ #if UNITY_EDITOR
+ // ParticleSystemRenderer always goes with ParticleSystem
+ virtual int GetCoupledComponentClassID() const { return ClassID(ParticleSystemRenderer); }
+ #endif
+
+
+ static void* UpdateFunction (void* rawData);
+
+ static void BeginUpdateAll();
+ static void EndUpdateAll();
+ static void Update(ParticleSystem& system, float deltaTime, bool fixedTimeStep, bool useProcedural, int rayBudget = 0);
+
+ static bool SystemWannaRayCast(const ParticleSystem& system);
+ static bool SystemWillRayCast(const ParticleSystem& system);
+ static void AssignRayBudgets();
+
+ static void SyncJobs();
+
+ static void Emit(ParticleSystem& system, const SubEmitterEmitCommand& command, ParticleSystemEmitMode emitMode);
+
+ // Client interface
+ void Simulate (float t, bool restart); // Fastforwards the particle system by simulating particles over given period of time, then pauses it.
+ void Play (bool autoPrewarm = true);
+ void Stop ();
+ void Pause ();
+ void Emit (int count);
+ void EmitParticleExternal(ParticleSystemParticle* particle);
+ void Clear (bool updateBounds = true);
+ void AutoPrewarm();
+
+ bool IsAlive () const;
+ bool IsPlaying () const;
+ bool IsPaused () const;
+ bool IsStopped () const;
+ float GetStartDelay() const;
+ void SetStartDelay(float value);
+ bool GetLoop () const;
+ void SetLoop (bool loop);
+ bool GetPlayOnAwake () const;
+ void SetPlayOnAwake (bool playOnAwake);
+ ParticleSystemSimulationSpace GetSimulationSpace () const;
+ void SetSimulationSpace (ParticleSystemSimulationSpace simulationSpace);
+ float GetSecPosition () const;
+ void SetSecPosition (float pos);
+ float GetLengthInSec () const;
+ void SetPlaybackSpeed (float speed);
+ float GetPlaybackSpeed () const;
+ void SetRayBudget (int rayBudget);
+ int GetRayBudget() const;
+
+ bool GetEnableEmission() const;
+ void SetEnableEmission(bool value);
+ float GetEmissionRate() const;
+ void SetEmissionRate(float value);
+ float GetStartSpeed() const;
+ void SetStartSpeed(float value);
+ float GetStartSize() const;
+ void SetStartSize(float value);
+ ColorRGBAf GetStartColor() const;
+ void SetStartColor(ColorRGBAf value);
+ float GetStartRotation() const;
+ void SetStartRotation(float value);
+ float GetStartLifeTime() const;
+ void SetStartLifeTime(float value);
+ float GetGravityModifier() const;
+ void SetGravityModifier(float value);
+ UInt32 GetRandomSeed() const;
+ void SetRandomSeed(UInt32 value);
+ int GetMaxNumParticles() const;
+ void SetMaxNumParticles(int value);
+
+ ShapeModule& GetShapeModule () { return m_ShapeModule; }
+
+
+ Matrix4x4f GetLocalToWorldMatrix() const;
+
+ void GetNumTiles(int& uvTilesX, int& uvTilesY) const;
+
+ void AllocateAllStructuresOfArrays();
+ void SetParticlesExternal (ParticleSystemParticle* particles, int size);
+ void GetParticlesExternal (ParticleSystemParticle* particles, int size);
+
+ int GetSafeCollisionEventSize () const;
+ int GetCollisionEventsExternal (int instanceID, MonoParticleCollisionEvent* collisionEvents, int size) const;
+
+ ParticleSystemParticles& GetParticles (int index = -1);
+ const ParticleSystemParticles& GetParticles (int index = -1) const;
+ size_t GetParticleCount () const;
+
+ ParticleSystemThreadScratchPad& GetThreadScratchPad () { return m_ThreadScratchpad; }
+
+ static void InitializeClass ();
+ static void CleanupClass () {};
+
+ void DidModifyMesh ();
+ void DidDeleteMesh ();
+
+#if UNITY_EDITOR
+ void TransformChanged();
+#endif
+
+ void RendererBecameVisible();
+ void RendererBecameInvisible();
+
+ static size_t EmitFromData (ParticleSystemEmissionState& emissionState, size_t& numContinuous, const ParticleSystemEmissionData& emissionData, const Vector3f velocity, float fromT, float toT, float dt, float length);
+private:
+ static void Update0 (ParticleSystem& system, const ParticleSystemReadOnlyState& roState, ParticleSystemState& state, float dt, bool fixedTimeStep);
+ static void Update1 (ParticleSystem& system, ParticleSystemParticles& ps, float dt, bool fixedTimeStep, bool useProcedural, int rayBudget = 0);
+ static void Update2 (ParticleSystem& system, const ParticleSystemReadOnlyState& roState, ParticleSystemState& state, bool fixedTimeStep);
+ static void Update1Incremental(ParticleSystem& system, const ParticleSystemReadOnlyState& roState, ParticleSystemState& state, ParticleSystemParticles& ps, size_t fromIndex, float dt, bool useProcedural);
+
+ static size_t EmitFromModules (const ParticleSystem& system, const ParticleSystemReadOnlyState& roState, ParticleSystemEmissionState& emissionState, size_t& numContinuous, const Vector3f velocity, float fromT, float toT, float dt);
+ static void StartModules (ParticleSystem& system, const ParticleSystemReadOnlyState& roState, ParticleSystemState& state, const ParticleSystemEmissionState& emissionState, Vector3f initialVelocity, const Matrix4x4f& matrix, ParticleSystemParticles& ps, size_t fromIndex, float dt, float t, size_t numContinuous, float frameOffset);
+ static void StartParticles(ParticleSystem& system, ParticleSystemParticles& ps, const float prevT, const float t, const float dt, const size_t numContinuous, size_t amountOfParticlesToEmit, float frameOffset);
+ static void StartParticlesProcedural(ParticleSystem& system, ParticleSystemParticles& ps, const float prevT, const float t, const float dt, const size_t numContinuous, size_t amountOfParticlesToEmit, float frameOffset);
+ static void UpdateProcedural(ParticleSystem& system, const ParticleSystemReadOnlyState& roState, ParticleSystemState& state, ParticleSystemParticles& ps);
+ static void UpdateModulesPreSimulationIncremental (const ParticleSystem& system, const ParticleSystemReadOnlyState& roState, const ParticleSystemState& state, ParticleSystemParticles& ps, const size_t fromIndex, const size_t toIndex, float dt);
+ static void UpdateModulesPostSimulationIncremental (const ParticleSystem& system, const ParticleSystemReadOnlyState& roState, ParticleSystemState& state, ParticleSystemParticles& ps, const size_t fromIndex, float dt);
+ static void UpdateModulesIncremental (const ParticleSystem& system, const ParticleSystemReadOnlyState& roState, ParticleSystemState& state, ParticleSystemParticles& ps, size_t fromIndex, float dt);
+ static void UpdateModulesNonIncremental (const ParticleSystem& system, const ParticleSystemParticles& ps, ParticleSystemParticlesTempData& psTemp, size_t fromIndex, size_t toIndex);
+ static void SimulateParticles (const ParticleSystemReadOnlyState& roState, ParticleSystemState& state, ParticleSystemParticles& ps, const size_t fromIndex, float dt);
+ static void PlaybackSubEmitterCommandBuffer(const ParticleSystem& shuriken, ParticleSystemState& state, bool fixedTimeStep);
+ static void UpdateBounds(const ParticleSystem& system, const ParticleSystemParticles& ps, ParticleSystemState& state);
+
+ static void AddStagingBuffer(ParticleSystem& system);
+ static int CalculateMaximumSubEmitterEmitCount(ParticleSystem& shuriken, ParticleSystemState& state, float deltaTime, bool fixedTimeStep);
+ static int SetupSubEmitters(ParticleSystem& shuriken, ParticleSystemState& state);
+
+ static bool CheckSupportsProcedural(const ParticleSystem& system);
+ static bool DetermineSupportsProcedural(const ParticleSystem& system);
+
+ bool ComputePrewarmStartParameters(float& prewarmTime, float t);
+
+ void SetUsesAxisOfRotation();
+ void SetUsesEmitAccumulator(int numAccumulators);
+ void SetUsesRotationalSpeed();
+ void KeepUpdating();
+ void Cull();
+
+ size_t AddNewParticles(ParticleSystemParticles& particles, size_t newParticles) const;
+ size_t LimitParticleCount(size_t requestSize) const;
+ float CalculateSubEmitterMaximumLifeTime(float parentLifeTime) const;
+
+ bool GetIsDistanceEmitter() const;
+
+ void AddToManager();
+ void RemoveFromManager();
+
+ ParticleSystemParticles m_Particles[kNumParticleBuffers];
+ ParticleSystemParticles m_ParticlesStaging; // staging buffer for emitting into the emitter
+ ParticleSystemReadOnlyState* m_ReadOnlyState;
+ ParticleSystemState* m_State;
+ InitialModule m_InitialModule;
+ ShapeModule m_ShapeModule;
+ EmissionModule m_EmissionModule;
+
+ // Dependent on energy value
+ SizeModule* m_SizeModule;
+ RotationModule* m_RotationModule; // @TODO: Requires outputs angular velocity and thus requires integration (Inconsistent with other modules in this group)
+ ColorModule* m_ColorModule;
+ UVModule* m_UVModule;
+
+ // Dependent on energy value
+ VelocityModule* m_VelocityModule;
+ ForceModule* m_ForceModule;
+ ExternalForcesModule* m_ExternalForcesModule;
+
+ // Depends on velocity and modifies velocity
+ ClampVelocityModule* m_ClampVelocityModule;
+
+ // Dependent on velocity value
+ SizeBySpeedModule* m_SizeBySpeedModule;
+ RotationBySpeedModule* m_RotationBySpeedModule;
+ ColorBySpeedModule* m_ColorBySpeedModule;
+
+ // Dependent on a position and velocity
+ CollisionModule* m_CollisionModule;
+
+ SubModule* m_SubModule;
+
+ ParticleSystemThreadScratchPad m_ThreadScratchpad;
+
+ RayBudgetState m_RayBudgetState;
+ int m_RayBudget;
+
+private:
+ int m_EmittersIndex;
+
+#if UNITY_EDITOR
+public:
+ int m_EditorRandomSeedIndex;
+ ListNode<ParticleSystem> m_EditorListNode;
+ friend class ParticleSystemEditor;
+#endif
+ friend class ParticleSystemRenderer;
+};
+
+#endif // SHURIKEN_H