void CTEParticleRenderer::SimulateParticles( CParticleSimulateIterator *pIterator )
{
	StandardParticle_t *pParticle = (StandardParticle_t*)pIterator->GetFirst();
	while ( pParticle )
	{
		// Remove the particle?
		SetParticleLifetime(pParticle, GetParticleLifetime(pParticle) - pIterator->GetTimeDelta());
		if(GetParticleLifetime(pParticle) < 0)
		{
			pIterator->RemoveParticle( pParticle );
		}
		else
		{
			float	ft = pIterator->GetTimeDelta();
			float	time3 = 15.0 * ft;
			float	time2 = 10.0 * ft;
			float	time1 = 5.0 * ft;
			float	dvel = 4* ft ;

			float grav = ft * sv_gravity.GetFloat() * 0.05f;

			int		(*colorIndex)[3];
			int		iRamp;

			switch(GetParticleType(pParticle))
			{
			case pt_static:
				break;

			case pt_fire:
				pParticle->m_EffectDataWord += (unsigned short)(time1 * (1 << SIMSHIFT));
				iRamp = pParticle->m_EffectDataWord >> SIMSHIFT;
				if(iRamp >= 6)
				{
					pParticle->m_Lifetime = -1;
				}
				else
				{
					colorIndex = &ramp3[ iRamp ];
					pParticle->SetColor((float)(*colorIndex)[0] / 255.0f, (float)(*colorIndex)[1] / 255.0f, (float)(*colorIndex)[2] / 255.0f);
				}
				pParticle->m_Velocity[2] += grav;
				break;

			case pt_explode:
				pParticle->m_EffectDataWord += (unsigned short)(time2 * (1 << SIMSHIFT));
				iRamp = pParticle->m_EffectDataWord >> SIMSHIFT;
				if(iRamp >= 8)
				{
					pParticle->m_Lifetime = -1;
				}
				else
				{
					colorIndex = &ramp1[ iRamp ];
					pParticle->SetColor((float)(*colorIndex)[0] / 255.0f, (float)(*colorIndex)[1] / 255.0f, (float)(*colorIndex)[2] / 255.0f);
				}
				pParticle->m_Velocity = pParticle->m_Velocity + pParticle->m_Velocity * dvel;
				pParticle->m_Velocity[2] -= grav;
				break;

			case pt_explode2:
				pParticle->m_EffectDataWord += (unsigned short)(time3 * (1 << SIMSHIFT));
				iRamp = pParticle->m_EffectDataWord >> SIMSHIFT;
				if(iRamp >= 8)
				{
					pParticle->m_Lifetime = -1;
				}
				else
				{
					colorIndex = &ramp2[ iRamp ];
					pParticle->SetColor((float)(*colorIndex)[0] / 255.0f, (float)(*colorIndex)[1] / 255.0f, (float)(*colorIndex)[2] / 255.0f);
				}
				pParticle->m_Velocity = pParticle->m_Velocity - pParticle->m_Velocity * ft;
				pParticle->m_Velocity[2] -= grav;
				break;

			case pt_grav:
				pParticle->m_Velocity[2] -= grav * 20;
				break;
			case pt_slowgrav:
				pParticle->m_Velocity[2] = grav;
				break;

			case pt_vox_grav:
				pParticle->m_Velocity[2] -= grav * 8;
				break;
				
			case pt_vox_slowgrav:
				pParticle->m_Velocity[2] -= grav * 4;
				break;

				
			case pt_blob:
			case pt_blob2:
				pParticle->m_EffectDataWord += (unsigned short)(time2 * (1 << SIMSHIFT));
				iRamp = pParticle->m_EffectDataWord >> SIMSHIFT;
				if(iRamp >= SPARK_COLORCOUNT)
				{
					pParticle->m_EffectDataWord = 0;
					iRamp = 0;
				}
				
				colorIndex = &gSparkRamp[ iRamp ];
				pParticle->SetColor((float)(*colorIndex)[0] / 255.0f, (float)(*colorIndex)[1] / 255.0f, (float)(*colorIndex)[2] / 255.0f);
				
				pParticle->m_Velocity[0] -= pParticle->m_Velocity[0]*0.5*ft;
				pParticle->m_Velocity[1] -= pParticle->m_Velocity[1]*0.5*ft;
				pParticle->m_Velocity[2] -= grav * 5;

				if ( random->RandomInt(0,3) )
				{
					SetParticleType(pParticle, pt_blob);
					pParticle->SetAlpha(0);
				}
				else
				{
					SetParticleType(pParticle, pt_blob2);
					pParticle->SetAlpha(255.9f);
				}
				break;
			}
			// Update position.
			pParticle->m_Pos = pParticle->m_Pos + pParticle->m_Velocity * ft;
		}

		pParticle = (StandardParticle_t*)pIterator->GetNext();
	}
}
示例#2
0
	void PartSysParser::ParseEmitter(const TabFileRecord& record) {
		auto systemName = record[COL_PARTSYS_NAME].AsString();

		auto& system = mSpecs[tolower(systemName)];
		// Create it on demand
		if (!system) {
			system = std::make_shared<PartSysSpec>(systemName);
		}

		// Add the emitter
		auto emitter = system->CreateEmitter(record[COL_EMITTER_NAME].AsString());

		ParseOptionalFloat(record, COL_DELAY, "Delay", [&] (float value) {
			                   emitter->SetDelay(value / 30.0f);
		                   });

		ParseLifespan(record, emitter);

		ParseParticleLifespan(record, emitter);

		ParseParticleRate(record, emitter);

		ParseOptionalEnum<PartSysEmitterSpace>(record, COL_EMITTER_SPACE, "emitter space", EmitterSpaceMapping, [&](auto space) {
			                                       emitter->SetSpace(space);
		                                       });

		ParseEmitterNodeName(record, emitter);

		ParseOptionalEnum<PartSysCoordSys>(record, COL_EMITTER_COORD_SYS, "emitter coord sys", CoordSysMapping, [&](auto coordSys) {
			                                   emitter->SetCoordSys(coordSys);
		                                   });

		ParseOptionalEnum<PartSysCoordSys>(record, COL_EMITTER_OFFSET_COORD_SYS, "emitter offset coord sys", CoordSysMapping, [&](auto coordSys) {
			                                   emitter->SetOffsetCoordSys(coordSys);
		                                   });

		ParseOptionalEnum<PartSysParticleType>(record, COL_PARTICLE_TYPE, "particle type", ParticleTypeMapping, [&](PartSysParticleType type) {
			                                       emitter->SetParticleType(type);
		                                       });

		ParseOptionalEnum<PartSysBlendMode>(record, COL_BLEND_MODE, "blend mode", BlendModeMapping, [&](auto mode) {
			                                    emitter->SetBlendMode(mode);
		                                    });

		ParseMaterial(record, emitter);

		ParseOptionalEnum<PartSysCoordSys>(record, COL_PARTICLE_POS_COORD_SYS, "particle pos coord sys", CoordSysMapping, [&](auto coordSys) {
			                                   emitter->SetParticlePosCoordSys(coordSys);
		                                   });
		ParseOptionalEnum<PartSysCoordSys>(record, COL_PARTICLE_VELOCITY_COORD_SYS, "particle velocity coord sys", CoordSysMapping, [&](auto coordSys) {
			                                   emitter->SetParticleVelocityCoordSys(coordSys);
		                                   });
		ParseOptionalEnum<PartSysParticleSpace>(record, COL_PARTICLE_SPACE, "particle space", ParticleSpaceMapping, [&](auto space) {
			                                        emitter->SetParticleSpace(space);
		                                        });

		ParseMesh(record, emitter);

		// Parse the bounding box
		ParseOptionalFloat(record, COL_BB_LEFT, "bb left", [&](float val) {
			                   emitter->SetBoxLeft(val);
		                   });
		ParseOptionalFloat(record, COL_BB_TOP, "bb top", [&](float val) {
			                   emitter->SetBoxTop(val);
		                   });
		ParseOptionalFloat(record, COL_BB_RIGHT, "bb right", [&](float val) {
			                   emitter->SetBoxRight(val);
		                   });
		ParseOptionalFloat(record, COL_BB_BOTTOM, "bb bottom", [&](float val) {
			                   emitter->SetBoxBottom(val);
		                   });

		for (int paramId = 0; paramId <= part_attractorBlend; paramId++) {
			int colIdx = 22 + paramId;
			auto col = record[colIdx];
			if (col) {
				bool success;
				std::unique_ptr<PartSysParam> param(ParserParams::Parse((PartSysParamId) paramId,
				                                                        col,
				                                                        emitter->GetLifespan(),
				                                                        emitter->GetParticleLifespan(),
				                                                        success));
				if (success) {
					emitter->SetParam((PartSysParamId)paramId, param);
				} else {
					logger->warn("Unable to parse particle system param {} for particle system {} and emitter {} with value {}",
					             paramId, systemName, emitter->GetName(), col.AsString());
				}
			}
		}

	}