#include "trenderer.h" #include #include "particlesmanager.h" /* EXPLANATION: ParticlesManager improves the old particles system as follows - the particles manager stores the last particles configuration which had some particle rendered by a thread. Under normal cicumstances, this means that every thread has the particles configuration that rendered last. In case a trail was set, such frame is that beyond the trail. This managemer works well on the assumption that each thread builds particle in an incremental timeline. */ //-------------------------------------------------------------------------------------------------- DEFINE_CLASS_CODE(ParticlesManager::FxData, 110) //-------------------------------------------------------------------------------------------------- typedef std::map FramesMap; //************************************************************************************************ // Preliminaries //************************************************************************************************ class ParticlesManagerGenerator final : public TRenderResourceManagerGenerator { public: ParticlesManagerGenerator() : TRenderResourceManagerGenerator(true) {} TRenderResourceManager *operator()(void) override { return new ParticlesManager; } }; MANAGER_FILESCOPE_DECLARATION(ParticlesManager, ParticlesManagerGenerator); //************************************************************************************************ // FrameData implementation //************************************************************************************************ ParticlesManager::FrameData::FrameData(FxData *fxData) : m_fxData(fxData) , m_frame((std::numeric_limits::min)()) , m_calculated(false) , m_maxTrail(-1) , m_totalParticles(0) { m_fxData->addRef(); } //------------------------------------------------------------------------- ParticlesManager::FrameData::~FrameData() { m_fxData->release(); } //------------------------------------------------------------------------- void ParticlesManager::FrameData::buildMaxTrail() { // Store the maximum trail of each particle std::list::iterator it; for (it = m_particles.begin(); it != m_particles.end(); ++it) m_maxTrail = std::max(m_maxTrail, it->trail); } //------------------------------------------------------------------------- void ParticlesManager::FrameData::clear() { m_frame = (std::numeric_limits::min)(); m_particles.clear(); m_random = TRandom(); m_calculated = false; m_maxTrail = -1; m_totalParticles = 0; } //************************************************************************************************ // FxData implementation //************************************************************************************************ ParticlesManager::FxData::FxData() : TSmartObject(m_classCode) {} //************************************************************************************************ // ParticlesContainer implementation //************************************************************************************************ ParticlesManager *ParticlesManager::instance() { return static_cast( ParticlesManager::gen()->getManager(TRenderer::renderId())); } //------------------------------------------------------------------------- ParticlesManager::ParticlesManager() : m_renderStatus(-1) {} //------------------------------------------------------------------------- ParticlesManager::~ParticlesManager() { // Release all fxDatas std::map::iterator it, end = m_fxs.end(); for (it = m_fxs.begin(); it != end; ++it) it->second->release(); } //------------------------------------------------------------------------- void ParticlesManager::onRenderStatusStart(int renderStatus) { m_renderStatus = renderStatus; } //------------------------------------------------------------------------- ParticlesManager::FrameData *ParticlesManager::data(unsigned long fxId) { QMutexLocker locker(&m_mutex); std::map::iterator it = m_fxs.find(fxId); if (it == m_fxs.end()) { it = m_fxs.insert(std::make_pair(fxId, new FxData)).first; it->second->addRef(); } FxData *fxData = it->second; FrameData *d = fxData->m_frames.localData(); if (!d) { d = new FrameData(fxData); fxData->m_frames.setLocalData(d); } return d; }