// // UVModule.cpp // cocos2d_libs // // Created by 徐俊杰 on 2020/4/24. // #include "rparticle/Modules/UVModule.h" //#include "UnityPrefix.h" //#include "rparticle/Modules/UVModule.h" //#include "Runtime/BaseClasses/ObjectDefines.h" #include "rparticle/Serialize/TransferFunctions/SerializeTransfer.h" #include "rparticle/ParticleSystemParticle.h" #include "rparticle/ParticleSystemCurves.h" #include "rparticle/ParticleSystemUtils.h" #include "rparticle/Math/Random/Random.h" #include "2d/CCSpriteFrameCache.h" NS_RRP_BEGIN template void UpdateWholeSheetTpl(float cycles, const MinMaxCurve& curve, const ParticleSystemParticles& ps, float* tempSheetIndex, size_t fromIndex, size_t toIndex) { for (size_t q = fromIndex; q < toIndex; ++q) tempSheetIndex[q] = Repeat (cycles * Evaluate(curve, NormalizedTime(ps, q), GenerateRandom(ps.randomSeed[q] + kParticleSystemUVCurveId)), 1.0f); } UVModule::UVModule () : ParticleSystemModule(false) , m_Mode(kModeGrid) , m_TilesX (1), m_TilesY (1) , m_AnimationType (kWholeSheet) , m_RowIndex (0) , m_Cycles (1.0f) , m_RandomRow (true) , _frameNamePrefix("") , _frameStartIndex(0) , _frameEndIndex(0) , _isFramesDirty(true) {} void UVModule::RefreshFrames (std::vector& vertextInfos) { if (m_Mode != kModeSprites) return; if (!_isFramesDirty) return; if (_frameNamePrefix.empty() || _frameStartIndex < 0 || _frameEndIndex < 0 || _frameStartIndex >= _frameEndIndex) return; vertextInfos.clear(); for (int i = _frameStartIndex; i <= _frameEndIndex; i++) { //char name[_frameNamePrefix.size() + 15]; //snprintf(name, 0x100, "%s%i.png", _frameNamePrefix.c_str(), i); auto name = _frameNamePrefix + std::to_string(i) + ".png"; auto sprite = cocos2d::SpriteFrameCache::getInstance()->getSpriteFrameByName(name); if (!sprite) continue; vertextInfos.push_back(RRP_PARTICLEQUAD_VERTEX_INFO::Create(sprite->getTexture(), sprite->getRect(), sprite->isRotated(), sprite->getOffset(), sprite->getOriginalSize())); } #if REDREAM_EDITOR _frameCount = vertextInfos.size(); #endif _isFramesDirty = false; } void UVModule::Update (const ParticleSystemParticles& ps, float* tempSheetIndex, size_t fromIndex, size_t toIndex) { const float cycles = m_Cycles; DebugAssert(toIndex <= ps.array_size ()); if (m_AnimationType == kSingleRow) // row { int rows = m_TilesY; float animRange = (1.0f / (m_TilesX * rows)) * m_TilesX; if(m_RandomRow) { for (size_t q = fromIndex; q < toIndex; ++q) { const float t = cycles * Evaluate(m_Curve, NormalizedTime(ps, q), GenerateRandom(ps.randomSeed[q] + kParticleSystemUVCurveId)); const float x = Repeat (t, 1.0f); const float randomValue = GenerateRandom(ps.randomSeed[q] + kParticleSystemUVRowSelectionId); const float startRow = Floorf (randomValue * rows); float from = startRow * animRange; float to = from + animRange; tempSheetIndex[q] = Lerp (from, to, x); } } else { const float startRow = Floorf(m_RowIndex * animRange * rows); float from = startRow * animRange; float to = from + animRange; for (size_t q = fromIndex; q < toIndex; ++q) { const float t = cycles * Evaluate(m_Curve, NormalizedTime(ps, q), GenerateRandom(ps.randomSeed[q] + kParticleSystemUVCurveId)); const float x = Repeat (t, 1.0f); tempSheetIndex[q] = Lerp (from, to, x); } } } else if (m_AnimationType == kWholeSheet) // grid || row { if(m_Curve.minMaxState == kMMCScalar) UpdateWholeSheetTpl(m_Cycles, m_Curve, ps, tempSheetIndex, fromIndex, toIndex); else if (m_Curve.IsOptimized() && m_Curve.UsesMinMax ()) UpdateWholeSheetTpl(m_Cycles, m_Curve, ps, tempSheetIndex, fromIndex, toIndex); else if(m_Curve.IsOptimized()) UpdateWholeSheetTpl(m_Cycles, m_Curve, ps, tempSheetIndex, fromIndex, toIndex); else UpdateWholeSheetTpl(m_Cycles, m_Curve, ps, tempSheetIndex, fromIndex, toIndex); } else { Assert(!"Animation mode not implemented!"); } } void UVModule::CheckConsistency () { m_Mode = clamp (m_Mode, 0, kNumModes-1); m_AnimationType = clamp (m_AnimationType, 0, kNumAnimationTypes-1); m_TilesX = std::max (1, m_TilesX); m_TilesY = std::max (1, m_TilesY); m_Cycles = std::max (1, (int)m_Cycles); m_RowIndex = clamp (m_RowIndex, 0, m_TilesY-1); m_Curve.SetScalar(clamp (m_Curve.GetScalar(), 0.0f, 1.0f)); } void UVModule::GetNumTiles(int& uvTilesX, int& uvTilesY) const { uvTilesX = m_TilesX; uvTilesY = m_TilesY; } template void UVModule::Transfer (TransferFunction& transfer) { ParticleSystemModule::Transfer (transfer); transfer.Transfer (m_Curve, "frameOverTime"); transfer.Transfer (m_TilesX, "tilesX"); transfer.Transfer (m_TilesY, "tilesY"); transfer.Transfer (m_AnimationType, "animationType"); transfer.Transfer (m_RowIndex, "rowIndex"); transfer.Transfer (m_Cycles, "cycles"); transfer.Transfer (m_RandomRow, "randomRow"); transfer.Align (); } INSTANTIATE_TEMPLATE_TRANSFER(UVModule) NS_RRP_END