⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 particle.cpp

📁 经典开源游戏glest的源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	
	ParticleSystem::initParticle(p, particleIndex);

	float x= random.randRange(-radius, radius);
	float y= random.randRange(-radius, radius);
	
	p->color= color;
	p->energy= 10000;
	p->pos= Vec3f(pos.x+x, pos.y, pos.z+y); 
	p->lastPos= p->pos;
	p->speed= Vec3f(0.0f, -speed, 0.0f) +  windSpeed;
	p->speed.x+= random.randRange(-0.005f, 0.005f);
	p->speed.y+= random.randRange(-0.005f, 0.005f);
}

bool SnowParticleSystem::deathTest(Particle *p){	
	return p->pos.y<0;
}

void SnowParticleSystem::setRadius(float radius){
	this->radius= radius;
}	

void SnowParticleSystem::setWind(float windAngle, float windSpeed){
	this->windSpeed.x= sinf(degToRad(windAngle))*windSpeed;
	this->windSpeed.y= 0.0f;
	this->windSpeed.z= cosf(degToRad(windAngle))*windSpeed;
}

// ===========================================================================
//  AttackParticleSystem
// ===========================================================================

AttackParticleSystem::AttackParticleSystem(int particleCount): ParticleSystem(particleCount){
	model= NULL;
	primitive= pQuad;
	offset= Vec3f(0.0f);
	gravity= 0.0f;
	direction= Vec3f(1.0f, 0.0f, 0.0f);
}

void AttackParticleSystem::render(ParticleRenderer *pr, ModelRenderer *mr){
	if(active){
		if(model!=NULL){
			pr->renderSingleModel(this, mr);
		}
		switch(primitive){
		case pQuad:
			pr->renderSystem(this);
			break;
		case pLine:
			pr->renderSystemLine(this);
			break;
		default:
			assert(false);
		}
	}
}

AttackParticleSystem::Primitive AttackParticleSystem::strToPrimitive(const string &str){
	if(str=="quad"){
		return pQuad;
	}
	else if(str=="line"){
		return pLine;
	}
	else{
		throw "Unknown particle primitive: " + str;
	}
}

// ===========================================================================
//  ProjectileParticleSystem
// ===========================================================================

ProjectileParticleSystem::ProjectileParticleSystem(int particleCount): AttackParticleSystem(particleCount){
	setEmissionRate(20);
	setColor(Vec4f(1.0f, 0.3f, 0.0f, 0.5f));
	setMaxParticleEnergy(100);
	setVarParticleEnergy(50);
	setParticleSize(0.4f);
	setSpeed(0.14f);

	trajectory= tLinear;
	trajectorySpeed= 1.0f;
	trajectoryScale= 1.0f;
	trajectoryFrequency = 1.0f;

	nextParticleSystem= NULL;
}

ProjectileParticleSystem::~ProjectileParticleSystem(){
	if(nextParticleSystem!=NULL){
		nextParticleSystem->prevParticleSystem= NULL;
	}
}

void ProjectileParticleSystem::link(SplashParticleSystem *particleSystem){
	nextParticleSystem= particleSystem;
	nextParticleSystem->setState(sPause);
	nextParticleSystem->prevParticleSystem= this;
}

void ProjectileParticleSystem::update(){

	if(state==sPlay){

		lastPos= pos;
		flatPos+= zVector * trajectorySpeed;
		Vec3f targetVector= endPos - startPos;
		Vec3f currentVector= flatPos - startPos;

		// ratio
		float t= clamp(currentVector.length() / targetVector.length(), 0.0f, 1.0f);
				
		// trajectory
		switch(trajectory){
		case tLinear:
			{	
				pos= flatPos;
			}
			break;

		case tParabolic:
			{
				float scaledT= 2.0f * (t-0.5f);
				float paraboleY= (1.0f-scaledT*scaledT) * trajectoryScale;

				pos = flatPos;
				pos.y+= paraboleY;
			}
			break;

		case tSpiral:
			{
				pos= flatPos;
				pos+= xVector * cos(t*trajectoryFrequency*targetVector.length())*trajectoryScale;
				pos+= yVector * sin(t*trajectoryFrequency*targetVector.length())*trajectoryScale;
			}
			break;

		default:
			assert(false);
		}
		
		direction= pos - lastPos;
		direction.normalize();

		//arrive destination
		if( flatPos.dist(endPos)<0.5f ){
			state= sFade;
			model= NULL;

			if(particleObserver!=NULL){
				particleObserver->update(this);
			}

			if(nextParticleSystem!=NULL){
				nextParticleSystem->setState(sPlay);
				nextParticleSystem->setPos(endPos);
			}
		}
	}

	ParticleSystem::update();
}

void ProjectileParticleSystem::initParticle(Particle *p, int particleIndex){

	ParticleSystem::initParticle(p, particleIndex);
		
	float t= static_cast<float>(particleIndex)/emissionRate;
		
	p->pos=	pos + (lastPos - pos) * t;
	p->lastPos= lastPos;
	p->speed= Vec3f(random.randRange(-0.1f, 0.1f), random.randRange(-0.1f, 0.1f), random.randRange(-0.1f, 0.1f)) * speed;
	p->accel= Vec3f(0.0f, -gravity, 0.0f);
	
	updateParticle(p);
}

void ProjectileParticleSystem::updateParticle(Particle *p){
	float energyRatio= clamp(static_cast<float>(p->energy)/maxParticleEnergy, 0.f, 1.f);
		
	p->lastPos+= p->speed;
	p->pos+= p->speed;
	p->speed+= p->accel;
	p->color = color * energyRatio + colorNoEnergy * (1.0f-energyRatio);
	p->size = particleSize * energyRatio + sizeNoEnergy * (1.0f-energyRatio);
	p->energy--;
}

void ProjectileParticleSystem::setPath(Vec3f startPos, Vec3f endPos){
	
	//compute axis
	zVector= endPos - startPos;
	zVector.normalize();
	yVector= Vec3f(0.0f, 1.0f, 0.0f);
	xVector= zVector.cross(yVector);
	
	//apply offset
	startPos+= xVector * offset.x;
	startPos+= yVector * offset.y;
	startPos+= zVector * offset.z;

	pos= startPos;
	lastPos= startPos;
	flatPos= startPos;

	//recompute axis
	zVector= endPos - startPos;
	zVector.normalize();
	yVector= Vec3f(0.0f, 1.0f, 0.0f);
	xVector= zVector.cross(yVector);

	// set members
	this->startPos= startPos;
	this->endPos= endPos;
}

ProjectileParticleSystem::Trajectory ProjectileParticleSystem::strToTrajectory(const string &str){
	if(str=="linear"){
		return tLinear;
	}
	else if(str=="parabolic"){
		return tParabolic;
	}
	else if(str=="spiral"){
		return tSpiral;
	}
	else{
		throw "Unknown particle system trajectory: " + str;
	}
}

// ===========================================================================
//  SplashParticleSystem
// ===========================================================================

SplashParticleSystem::SplashParticleSystem(int particleCount): AttackParticleSystem(particleCount){
	setColor(Vec4f(1.0f, 0.3f, 0.0f, 0.8f));
	setMaxParticleEnergy(100);
	setVarParticleEnergy(50);
	setParticleSize(1.0f);
	setSpeed(0.003f);

	prevParticleSystem= NULL;

	emissionRateFade= 1;
	verticalSpreadA= 1.0f;
	verticalSpreadB= 0.0f;
	horizontalSpreadA= 1.0f;
	horizontalSpreadB= 0.0f;
}

SplashParticleSystem::~SplashParticleSystem(){
	if(prevParticleSystem!=NULL){
		prevParticleSystem->nextParticleSystem= NULL;	
	}
}

void SplashParticleSystem::update(){
	ParticleSystem::update();
	if(state!=sPause){
		emissionRate-= emissionRateFade;
	}
}

void SplashParticleSystem::initParticle(Particle *p, int particleIndex){
	p->pos= pos;
	p->lastPos= p->pos;
	p->energy= maxParticleEnergy;
	p->size= particleSize;
	p->color= color;
	
	p->speed= Vec3f(
		horizontalSpreadA * random.randRange(-1.0f, 1.0f) + horizontalSpreadB, 
		verticalSpreadA * random.randRange(-1.0f, 1.0f) + verticalSpreadB, 
		horizontalSpreadA * random.randRange(-1.0f, 1.0f) + horizontalSpreadB);
	p->speed.normalize();
	p->speed= p->speed * speed;

	p->accel= Vec3f(0.0f, -gravity, 0.0f);
}

void SplashParticleSystem::updateParticle(Particle *p){
	float energyRatio= clamp(static_cast<float>(p->energy)/maxParticleEnergy, 0.f, 1.f);
		
	p->lastPos= p->pos;
	p->pos= p->pos + p->speed;
	p->speed= p->speed + p->accel;
	p->energy--;
	p->color = color * energyRatio + colorNoEnergy * (1.0f-energyRatio);
	p->size = particleSize * energyRatio + sizeNoEnergy * (1.0f-energyRatio);
}

// ===========================================================================
//  ParticleManager
// ===========================================================================

ParticleManager::~ParticleManager(){
	end();
}

void ParticleManager::render(ParticleRenderer *pr, ModelRenderer *mr) const{
	list<ParticleSystem*>::const_iterator it;

	for (it=particleSystems.begin(); it!=particleSystems.end(); it++){
		if((*it)->getVisible()){
			(*it)->render(pr, mr);
		}
	}
}

void ParticleManager::update(){
	list<ParticleSystem*>::iterator it;

	for (it=particleSystems.begin(); it!=particleSystems.end(); it++){
		(*it)->update();
		if((*it)->isEmpty()){
			delete *it;
			*it= NULL;
		}
	}
	particleSystems.remove(NULL);
}

void ParticleManager::manage(ParticleSystem *ps){
	particleSystems.push_back(ps);
}

void ParticleManager::end(){
	while(!particleSystems.empty()){
		delete particleSystems.front();
		particleSystems.pop_front();
	}
}

}}//end namespace

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -