123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248 |
- //
- // ParticleSystemModule.cpp
- // libcocos2d Mac
- //
- // Created by 徐俊杰 on 2020/4/24.
- //
- #include "rparticle/Modules/ParticleSystemModule.h"
- #include "rparticle/Serialize/TransferFunctions/SerializeTransfer.h"
- #include "base/CCDirector.h"
- #include "rparticle/Utilities/Transform.h"
- #include "renderer/CCTexture2D.h"
- #define zero ZERO
- #define one ONE
- #define SetIdentity setIdentity
- NS_RRP_BEGIN
- RRP_PARTICLEQUAD_VERTEX_INFO RRP_PARTICLEQUAD_VERTEX_INFO::Create(cocos2d::Texture2D *texture, const cocos2d::Rect& pointRect, bool isRotaed, const cocos2d::Vec2& offset, const cocos2d::Vec2& originalSize)
- {
- // convert to Tex coords
- RRP_PARTICLEQUAD_VERTEX_INFO _vertexInfo;
-
- const auto& rect = pointRect;
-
- GLfloat wide = (GLfloat) pointRect.size.width;
- GLfloat high = (GLfloat) pointRect.size.height;
-
- float rw = rect.size.width;
- float rh = rect.size.height;
-
- if (isRotaed)
- std::swap(rw, rh);
-
- if (texture)
- {
- wide = (GLfloat)texture->getPixelsWide();
- high = (GLfloat)texture->getPixelsHigh();
- }
-
- #if CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL
- GLfloat left = (rect.origin.x*2+1) / (wide*2);
- GLfloat bottom = (rect.origin.y*2+1) / (high*2);
- GLfloat right = left + (rw*2-2) / (wide*2);
- GLfloat top = bottom + (rh*2-2) / (high*2);
- #else
- GLfloat left = rect.origin.x / wide;
- GLfloat bottom = rect.origin.y / high;
- GLfloat right = left + rw / wide;
- GLfloat top = bottom + rh / high;
- #endif // ! CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL
-
- // Important. Texture in cocos2d are inverted, so the Y component should be inverted
- std::swap(top, bottom);
-
-
- // CCASSERT(_texNumber < 100, "纹理数量超过上限");
- //
- if (isRotaed)
- {
- _vertexInfo.bl.u = left;
- _vertexInfo.bl.v = top;
- _vertexInfo.br.u = left;
- _vertexInfo.br.v = bottom;
- _vertexInfo.tl.u = right;
- _vertexInfo.tl.v = top;
- _vertexInfo.tr.u = right;
- _vertexInfo.tr.v = bottom;
-
- }
- else
- {
- _vertexInfo.bl.u = left;
- _vertexInfo.bl.v = bottom;
- _vertexInfo.br.u = right;
- _vertexInfo.br.v = bottom;
- _vertexInfo.tl.u = left;
- _vertexInfo.tl.v = top;
- _vertexInfo.tr.u = right;
- _vertexInfo.tr.v = top;
- }
- // if (!offset.isZero()){
- // // CCLOG("");
- // }
- float originalSizeX_2 = 2 / originalSize.x; // 宽的一半的倒数
- float originalSizeY_2 = 2 / originalSize.y;
- float x1 = (pointRect.size.width * 0.5 - offset.x) * originalSizeX_2;
- float x2 = (pointRect.size.width * 0.5 + offset.x) * originalSizeX_2;
- float aspectRatio = originalSize.y / originalSize.x;
- float y1 = (pointRect.size.height * 0.5 - offset.y) * originalSizeY_2 * aspectRatio;
- float y2 = (pointRect.size.height * 0.5 + offset.y) * originalSizeY_2 * aspectRatio;
- _vertexInfo.centerPercentage.set(x1, x2, y1, y2);
-
- // auto halfScale = Vec2(pointRect.size.width / originalSize.x, pointRect.size.height / originalSize.y) * 0.5f;
- // auto offsetScale = Vec2(offset.x / originalSize.x, offset.y / originalSize.y);
- //
- // _vertexInfo.border.set(halfScale.x - offsetScale.x, halfScale.x + offsetScale.x, halfScale.y - offsetScale.y, halfScale.y + offsetScale.y);
-
- return _vertexInfo;
- }
- ParticleSystemReadOnlyState::ParticleSystemReadOnlyState()
- : lengthInSec (5.0f)
- , startDelay (0.0f)
- , speed (1.0f)
- , randomSeed (0)
- , looping (true)
- , prewarm (false)
- , scalingMode(0)
- , playOnAwake (true)
- , useLocalSpace (true)
- {
- }
- void ParticleSystemReadOnlyState::CheckConsistency()
- {
- lengthInSec = std::max(lengthInSec, 0.1f);
- lengthInSec = std::min(lengthInSec, 100000.0f); // Very large values can lead to editor locking up due to numerical instability.
- startDelay = std::max(startDelay, 0.0f);
- speed = std::max(speed, 0.0f);
- }
- float ParticleSystemReadOnlyState::GetRenderScale() const
- {
- return scale * CC_CONTENT_SCALE_FACTOR();
- }
- template<class TransferFunction>
- void ParticleSystemReadOnlyState::Transfer (TransferFunction& transfer)
- {
- TRANSFER (lengthInSec);
- TRANSFER (startDelay);
- TRANSFER (speed);
- TRANSFER (randomSeed);
- TRANSFER (looping);
- TRANSFER (prewarm);
- TRANSFER (playOnAwake);
- transfer.Transfer (useLocalSpace, "moveWithTransform");
- }
- INSTANTIATE_TEMPLATE_TRANSFER(ParticleSystemReadOnlyState)
- ParticleSystemState::ParticleSystemState (RParticleSystem* system_)
- : system(system_)
- , playing (false)
- , needRestart (true)
- , stopEmitting (false)
- , accumulatedDt (0.0f)
- , delayT (0.0f)
- , t (0.0f)
- , maxSize (0.0f)
- , isSubEmitter (false)
- , recordSubEmits(false)
- , cullTime(0.0)
- , culled(false)
- , numLoops(0)
- , invalidateProcedural(false)
- , supportsProcedural(true)
- , cachedForces(0)
- , numCachedForces(0)
- , cachedSubDataBirth(0)
- , numCachedSubDataBirth(0)
- , cachedSubDataCollision(0)
- , numCachedSubDataCollision(0)
- , cachedSubDataDeath(0)
- , numCachedSubDataDeath(0)
- , cachedCollisionPlanes(0)
- , numCachedCollisionPlanes(0)
- , rayBudget(0)
- , nextParticleToTrace(0)
- {
- ClearSubEmitterCommandBuffer();
-
- localToWorld.SetIdentity ();
- emitterVelocity = Vector3f::zero;
- emitterScale = Vector3f::one;
- minMaxAABB = MinMaxAABB (Vector3f::zero, Vector3f::zero);
- }
- void ParticleSystemState::Tick (const ParticleSystemReadOnlyState& constState, float dt)
- {
- t += dt;
-
- for(int i = 0; i < subEmitterCommandBuffer.commandCount; i++)
- subEmitterCommandBuffer.commands[i].timeAlive += dt;
-
- if (!constState.looping)
- t = std::min<float> (t, constState.lengthInSec);
- else
- if(t > constState.lengthInSec)
- {
- t -= constState.lengthInSec;
- numLoops++;
- }
- }
- void ParticleSystemState::ClearSubEmitterCommandBuffer()
- {
- if(cachedSubDataBirth)
- {
- for (int i = 0; i < numCachedSubDataBirth; ++i)
- {
- (cachedSubDataBirth+i)->~ParticleSystemSubEmitterData();
- }
- FREE_TEMP_MANUAL(cachedSubDataBirth);
- }
- if(cachedSubDataCollision)
- {
- for (int i = 0; i < numCachedSubDataCollision; ++i)
- {
- (cachedSubDataCollision+i)->~ParticleSystemSubEmitterData();
- }
- FREE_TEMP_MANUAL(cachedSubDataCollision);
- }
- if(cachedSubDataDeath)
- {
- for (int i = 0; i < numCachedSubDataDeath; ++i)
- {
- (cachedSubDataDeath+i)->~ParticleSystemSubEmitterData();
- }
- FREE_TEMP_MANUAL(cachedSubDataDeath);
- }
- if(subEmitterCommandBuffer.commands)
- FREE_TEMP_MANUAL(subEmitterCommandBuffer.commands);
-
- cachedSubDataBirth = cachedSubDataCollision = cachedSubDataDeath = 0;
- numCachedSubDataBirth = numCachedSubDataCollision = numCachedSubDataDeath = 0;
- subEmitterCommandBuffer.commands = 0;
- subEmitterCommandBuffer.commandCount = subEmitterCommandBuffer.maxCommandCount = 0;
- }
- template<class TransferFunction>
- void ParticleSystemState::Transfer (TransferFunction& transfer)
- {
- // TRANSFER_DEBUG (t);
- }
- INSTANTIATE_TEMPLATE_TRANSFER(ParticleSystemState)
- template<class TransferFunction>
- void ParticleSystemModule::Transfer (TransferFunction& transfer)
- {
- transfer.Transfer (m_Enabled, "enabled"); transfer.Align ();
- }
- INSTANTIATE_TEMPLATE_TRANSFER(ParticleSystemModule)
- NS_RRP_END
|