// // ParticleSystemModule.h // libcocos2d Mac // // Created by 徐俊杰 on 2020/4/24. // #ifndef ParticleSystemModule_h #define ParticleSystemModule_h #include "base/CCRef.h" #include "3d/CCPlane.h" //#include "cocos2d.h" #include "rparticle/Macros/RParticleMacros.h" #include "rparticle/Utilities/dynamic_array.h" #include "rparticle/ParticleSystemCommon.h" #include "rparticle/ParticleSystemCurves.h" namespace cocos2d { class Texture2D; }; NS_RRP_BEGIN #define DECLARE_MODULE(name) const char* GetName () { return #name; }// DEFINE_GET_TYPESTRING(name) class RParticleSystem; struct RRP_PARTICLEQUAD_BORDER { RRP_PARTICLEQUAD_BORDER() : left(1) , right(1) , bottom(1) , top(1) {} RRP_PARTICLEQUAD_BORDER(float l, float r, float b, float t) : left(l) , right(r) , bottom(b) , top(t) {} float left; float right; float bottom; float top; void set(float l, float r, float b, float t) { left = l; right = r; bottom = b; top = t; } }; struct RRP_PARTICLEQUAD_VERTEX_INFO { RRP_PARTICLEQUAD_VERTEX_INFO() {} RRP_PARTICLEQUAD_VERTEX_INFO(RRP_PARTICLEQUAD_BORDER _centerPercentage, cocos2d::Tex2F _bl, cocos2d::Tex2F _br, cocos2d::Tex2F _tl, cocos2d::Tex2F _tr) : centerPercentage(_centerPercentage) , bl(_bl) , br(_br) , tl(_tl) , tr(_tr) {} static RRP_PARTICLEQUAD_VERTEX_INFO Create(cocos2d::Texture2D *_texture, const cocos2d::Rect& pointRect, bool isRotaed, const cocos2d::Vec2& offset, const cocos2d::Vec2& originalSize); // ------------- // | t% | // | --- | // | l% | · | r% | // | --- | // | b% | // ------------- RRP_PARTICLEQUAD_BORDER centerPercentage; // 以中心点为原点,四个方向边占原边的比值 0~1 cocos2d::Tex2F bl; cocos2d::Tex2F br; cocos2d::Tex2F tl; cocos2d::Tex2F tr; }; struct ParticleSystemEmissionState { ParticleSystemEmissionState() { Clear(); } inline void Clear() { m_ToEmitAccumulator = 0.0f; m_ParticleSpacing = 0.0f; } float m_ParticleSpacing; float m_ToEmitAccumulator; }; struct ParticleSystemEmissionData { enum { kMaxNumBursts = 4 }; int type; MinMaxCurve rate; float burstTime[kMaxNumBursts]; UInt16 burstParticleCount[kMaxNumBursts]; UInt8 burstCount; }; struct ParticleSystemSubEmitterData { ParticleSystemSubEmitterData() :maxLifetime(0.0f) ,startDelayInSec(0.0f) ,lengthInSec(0.0f) ,properties(0) {} ParticleSystemEmissionData emissionData; float maxLifetime; float startDelayInSec; float lengthInSec; int properties; RParticleSystem* emitter; }; // @TODO: Find "pretty" place for shared structs and enums? struct ParticleSystemEmitReplay { float t; float aliveTime; float emissionOffset; float emissionGap; int particlesToEmit; size_t numContinuous; UInt32 randomSeed; ParticleSystemEmitReplay (float inT, int inParticlesToEmit, float inEmissionOffset, float inEmissionGap, size_t inNumContinuous, UInt32 inRandomSeed) : t (inT), particlesToEmit (inParticlesToEmit), aliveTime(0.0F), emissionOffset(inEmissionOffset), emissionGap(inEmissionGap), numContinuous(inNumContinuous), randomSeed(inRandomSeed) {} }; struct SubEmitterInheritValues { SubEmitterInheritValues() : color(255, 255, 255, 255) //, size(1.0f, 1.0f, 1.0f) //, rotation(0.0f, 0.0f, 0.0f) , size(1.0f) , rotation(0.0f) , axisOfRotation(Vector3f::UNIT_Z) , lifetimeMultiplier(1.0f) , normalizedT(std::numeric_limits::infinity ()) , randomSeed(0) {} ColorRGBA32 color; //Vector3f size; //Vector3f rotation; float size; float rotation; Vector3f axisOfRotation; float lifetimeMultiplier; float normalizedT; UInt32 randomSeed; }; struct SubEmitterEmitCommand { SubEmitterEmitCommand(ParticleSystemEmissionState inEmissionState, Vector3f inPosition, Vector3f inVelocity, const SubEmitterInheritValues& inInheritValues, ParticleSystemSubType inSubEmitterType, int inSubEmitterIndex, int inParticlesToEmit, int inParticlesToEmitContinuous, float inParentT, float inDeltaTime) :emissionState(inEmissionState) ,position(inPosition) ,velocity(inVelocity) ,inheritValues(inInheritValues) ,subEmitterType(inSubEmitterType) ,subEmitterIndex(inSubEmitterIndex) ,particlesToEmit(inParticlesToEmit) ,particlesToEmitContinuous(inParticlesToEmitContinuous) ,deltaTime(inDeltaTime) ,parentT(inParentT) ,timeAlive(0.0f) { } ParticleSystemEmissionState emissionState; Vector3f position; Vector3f velocity; SubEmitterInheritValues inheritValues; ParticleSystemSubType subEmitterType; int subEmitterIndex; int particlesToEmit; int particlesToEmitContinuous; float deltaTime; float parentT; // Used for StartModules float timeAlive; }; struct ParticleSystemSubEmitCmdBuffer { ParticleSystemSubEmitCmdBuffer() :commands(0) ,commandCount(0) ,maxCommandCount(0) {} inline void AddCommand(const ParticleSystemEmissionState& emissionState, const Vector3f& initialPosition, const Vector3f& initialVelocity, const SubEmitterInheritValues& initiaValues, const ParticleSystemSubType type, const int index, const int particlesToEmit, const int particlesToEmitContinuous, const float parentT, const float dt) { commands[commandCount++] = SubEmitterEmitCommand(emissionState, initialPosition, initialVelocity, initiaValues, type, index, particlesToEmit, particlesToEmitContinuous, parentT, dt); } inline bool IsFull() { return commandCount >= maxCommandCount; } SubEmitterEmitCommand* commands; int commandCount; int maxCommandCount; // Mostly to assert/test against trashing memory }; struct ParticleSystemExternalCachedForce { Vector3f position; Vector3f direction; int forceType; float radius; float forceMain; float forceTurbulence; // not yet implemented }; // @TODO: Maybe there's a better name for this? ParticleSystemSerializedState? Some shit like that :) struct ParticleSystemReadOnlyState { ParticleSystemReadOnlyState(); void CheckConsistency(); float lengthInSec; float startDelay; float speed; UInt32 randomSeed; bool looping; bool prewarm; int scalingMode; bool playOnAwake; bool useLocalSpace; float scale; float GetRenderScale() const; template void Transfer (TransferFunction& transfer); }; struct ParticleSystemState { RParticleSystem* system; // state float accumulatedDt; float delayT; bool playing; bool needRestart; bool stopEmitting; size_t rayBudget; size_t nextParticleToTrace; bool GetIsSubEmitter() const { return isSubEmitter; } private: // When setting this we need to ensure some other things happen as well bool isSubEmitter; public: bool recordSubEmits; // Procedural mode / culling bool supportsProcedural; // With the current parameter set, does the emitter support procedural mode? bool invalidateProcedural; // This is set if anything changes from script at some point when running a system bool culled; // Is particle system currently culled? double cullTime; // Absolute time, so we need as double in case it runs for ages int numLoops; // Number of loops executed // per-frame Matrix4x4f localToWorld; Matrix4x4f worldToLocal; Vector3f emitterVelocity; Vector3f emitterScale; MinMaxAABB minMaxAABB; float maxSize; // Maximum size of particles due to setting from script float t; // Temp alloc stuff ParticleSystemSubEmitterData* cachedSubDataBirth; size_t numCachedSubDataBirth; ParticleSystemSubEmitterData* cachedSubDataCollision; size_t numCachedSubDataCollision; ParticleSystemSubEmitterData* cachedSubDataDeath; size_t numCachedSubDataDeath; ParticleSystemExternalCachedForce* cachedForces; size_t numCachedForces; cocos2d::Plane* cachedCollisionPlanes; size_t numCachedCollisionPlanes; ParticleSystemSubEmitCmdBuffer subEmitterCommandBuffer; dynamic_array emitReplay; ParticleSystemEmissionState emissionState; ParticleSystemState (RParticleSystem* system_); void Tick (const ParticleSystemReadOnlyState& constState, float dt); void ClearSubEmitterCommandBuffer(); void SetIsSubEmitter(bool inIsSubEmitter) { if(inIsSubEmitter) { stopEmitting = true; invalidateProcedural = true; } isSubEmitter = inIsSubEmitter; } template void Transfer (TransferFunction& transfer); }; class CC_DLL ParticleSystemModule//: public cocos2d::Ref { public: // DECLARE_SERIALIZE (ParticleSystemModule) template void Transfer (TransferFunction& transfer); ParticleSystemModule (bool enabled) : m_Enabled (enabled) {} virtual ~ParticleSystemModule () {} inline bool GetEnabled() const { return m_Enabled; } inline void SetEnabled(bool enabled) { m_Enabled = enabled; } private: // shared data bool m_Enabled; }; NS_RRP_END #endif /* ParticleSystemModule_h */