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