Beispiel #1
0
void ARX_PARTICLES_Update(EERIE_CAMERA * cam)  {
	
	ARX_PROFILE_FUNC();
	
	if(!ACTIVEBKG) {
		return;
	}
	
	if(ParticleCount == 0) {
		return;
	}
	
	const ArxInstant now = arxtime.now();
	
	long pcc = ParticleCount;
	
	for(size_t i = 0; i < MAX_PARTICLES && pcc > 0; i++) {

		PARTICLE_DEF * part = &particle[i];
		if(!part->exist) {
			continue;
		}

		long framediff = part->timcreation + part->tolive - now;
		long framediff2 = now - part->timcreation;
		
		if(framediff2 < long(part->delay)) {
			continue;
		}
		
		if(part->delay > 0) {
			part->timcreation += part->delay;
			part->delay=0;
			if((part->m_flags & DELAY_FOLLOW_SOURCE) && part->sourceionum != EntityHandle()
					&& entities[part->sourceionum]) {
				part->ov = *part->source;
				Entity * target = entities[part->sourceionum];
				Vec3f vector = (part->ov - target->pos) * Vec3f(1.f, 0.5f, 1.f);
				vector = glm::normalize(vector);
				part->move = vector * Vec3f(18.f, 5.f, 18.f) + randomVec(-0.5f, 0.5f);
				
			}
			continue;
		}
		
		if(!part->is2D) {

			EERIE_BKG_INFO * bkgData = getFastBackgroundData(part->ov.x, part->ov.z);

			if(!bkgData || !bkgData->treat) {
				part->exist = false;
				ParticleCount--;
				continue;
			}
		}
		
		if(framediff <= 0) {
			if((part->m_flags & FIRE_TO_SMOKE) && Random::getf() > 0.7f) {
				
				part->ov += part->move;
				part->tolive = part->tolive * 1.375f;
				part->m_flags &= ~FIRE_TO_SMOKE;
				part->tc = smokeparticle;
				part->scale = glm::abs(part->scale * 2.4f);
				part->rgb = Color3f::gray(.45f);
				part->move *= 0.5f;
				part->siz *= 1.f / 3;
				part->timcreation = now;
				
				framediff = part->tolive;
				
			} else {
				part->exist = false;
				ParticleCount--;
				continue;
			}
		}
		
		float val = (part->tolive - framediff) * 0.01f;
		
		Vec3f in = part->ov + part->move * val;
		Vec3f inn = in;
		
		if(part->m_flags & GRAVITY) {
			in.y = inn.y = inn.y + 1.47f * val * val;
		}
		
		float fd = float(framediff2) / float(part->tolive);
		float r = 1.f - fd;
		if(part->m_flags & FADE_IN_AND_OUT) {
			long t = part->tolive / 2;
			if(framediff2 <= t) {
				r = float(framediff2) / float(t);
			} else {
				r = 1.f - float(framediff2 - t) / float(t);
			}
		}
		
		if(!part->is2D) {
			
			Sphere sp;
			sp.origin = in;
			
			TexturedVertex out;
			EE_RTP(inn, out);
			
			if(out.rhw < 0 || out.p.z > cam->cdepth * fZFogEnd) {
				continue;
			}
			
			if(part->m_flags & SPLAT_GROUND) {
				float siz = part->siz + part->scale.x * fd;
				sp.radius = siz * 10.f;
				if(CheckAnythingInSphere(sp, EntityHandle_Player, CAS_NO_NPC_COL)) {
					if(Random::getf() < 0.9f) {
						Color3f rgb = part->rgb;
						PolyBoomAddSplat(sp, rgb, 0);
					}
					part->exist = false;
					ParticleCount--;
					continue;
				}
			}
			
			if(part->m_flags & SPLAT_WATER) {
				float siz = part->siz + part->scale.x * fd;
				sp.radius = siz * Random::getf(10.f, 30.f);
				if(CheckAnythingInSphere(sp, EntityHandle_Player, CAS_NO_NPC_COL)) {
					if(Random::getf() < 0.9f) {
						Color3f rgb = part->rgb * 0.5f;
						PolyBoomAddSplat(sp, rgb, 2);
					}
					part->exist = false;
					ParticleCount--;
					continue;
				}
			}
			
			if((part->m_flags & DISSIPATING) && out.p.z < 0.05f) {
				out.p.z *= 20.f;
				r *= out.p.z;
			}
		}
		
		if(r <= 0.f) {
			pcc--;
			continue;
		}
		
		if(part->m_flags & PARTICLE_GOLDRAIN) {
			float v = Random::getf(-0.1f, 0.1f);
			if(part->rgb.r + v <= 1.f && part->rgb.r + v > 0.f
				&& part->rgb.g + v <= 1.f && part->rgb.g + v > 0.f
				&& part->rgb.b + v <= 1.f && part->rgb.b + v > 0.f) {
				part->rgb = Color3f(part->rgb.r + v, part->rgb.g + v, part->rgb.b + v);
			}
		}
		
		Color color = (part->rgb * r).to<u8>();
		if(player.m_improve) {
			color.g = 0;
		}
		
		TextureContainer * tc = part->tc;
		if(tc == explo[0] && (part->m_flags & PARTICLE_ANIMATED)) {
			long animrange = part->cval2 - part->cval1;
			long num = long(float(framediff2) / float(part->tolive) * animrange);
			num = glm::clamp(num, long(part->cval1), long(part->cval2));
			tc = explo[num];
		}
		
		float siz = part->siz + part->scale.x * fd;

		RenderMaterial mat;
		mat.setTexture(tc);
		mat.setDepthTest(!(part->m_flags & PARTICLE_NOZBUFFER));
		
		if(part->m_flags & PARTICLE_SUB2) {
			mat.setBlendType(RenderMaterial::Subtractive2);
			color.a = glm::clamp(r * 1.5f, 0.f, 1.f) * 255;
		} else if(part->m_flags & SUBSTRACT) {
			mat.setBlendType(RenderMaterial::Subtractive);
		} else {
			mat.setBlendType(RenderMaterial::Additive);
		}
		
		if(part->m_flags & ROTATING) {
			if(!part->is2D) {
				float rott = MAKEANGLE(float(now + framediff2) * part->m_rotation);
				
				float temp = (part->zdec) ? 0.0001f : 2.f;
				float size = std::max(siz, 0.f);
				EERIEAddSprite(mat, in, size, color, temp, rott);
				
			}
		} else if(part->is2D) {
			
			float siz2 = part->siz + part->scale.y * fd;
			EERIEAddBitmap(mat, in, siz, siz2, tc, color);
			
		} else {
			
			float temp = (part->zdec) ? 0.0001f : 2.f;
			EERIEAddSprite(mat, in, siz, color, temp);
			
		}
		
		pcc--;
	}
}
Beispiel #2
0
void ARX_MAGICAL_FLARES_Update() {

	if(!flarenum)
		return;

	shinum++;
	if(shinum >= 10) {
		shinum = 1;
	}

	long TICKS = long(arxtime) - FRAMETICKS;
	FRAMETICKS = (unsigned long)(arxtime);
	if(TICKS < 0) {
		return;
	}

	bool key = !GInput->actionPressed(CONTROLS_CUST_MAGICMODE);

	RenderMaterial mat;
	mat.setBlendType(RenderMaterial::Additive);
	
	EERIE_LIGHT * light = lightHandleGet(torchLightHandle);
	
	for(long j = 1; j < 5; j++) {

		TextureContainer * surf;
		switch(j) {
			case 2:  surf = flaretc.lumignon; break;
			case 3:  surf = flaretc.lumignon2; break;
			case 4:  surf = flaretc.plasm; break;
			default: surf = flaretc.shine[shinum]; break;
		}

		mat.setTexture(surf);

		for(size_t i = 0; i < MAX_FLARES; i++) {

			FLARES & flare = magicFlares[i];

			if(!flare.exist || flare.type != j) {
				continue;
			}

			flare.tolive -= float(TICKS * 2);
			if(flare.flags & 1) {
				flare.tolive -= float(TICKS * 4);
			} else if (key) {
				flare.tolive -= float(TICKS * 6);
			}

			float z = (flare.tolive * 0.00025f);
			float s;
			if(flare.type == 1) {
				s = flare.size * 2 * z;
			} else if(flare.type == 4) {
				s = flare.size * 2.f * z + 10.f;
			} else {
				s = flare.size;
			}

			if(flare.tolive <= 0.f || flare.pos.y < -64.f || s < 3.f) {
				removeFlare(flare);
				continue;
			}

			if(flare.type == 1 && z < 0.6f)  {
				z = 0.6f;
			}

			Color3f c = flare.rgb * z;
			flare.tv.color = c.toRGB();
			flare.v.p = flare.tv.p;

			light->rgb = componentwise_max(light->rgb, c);

			if(lightHandleIsValid(flare.dynlight)) {
				EERIE_LIGHT * el = lightHandleGet(flare.dynlight);
				el->pos = flare.v.p;
				el->rgb = c;
			}

			mat.setDepthTest(flare.io != NULL);
			
			if(flare.bDrawBitmap) {
				s *= 2.f * minSizeRatio();
				EERIEAddBitmap(mat, flare.v.p, s, s, surf, Color::fromRGBA(flare.tv.color));
			} else {
				EERIEAddSprite(mat, flare.v.p, s * 0.025f + 1.f,
				               Color::fromRGBA(flare.tv.color), 2.f);
			}

		}
	}

	light->rgb = componentwise_min(light->rgb, Color3f::white);
}
void ARX_MAGICAL_FLARES_Update() {

	if(!g_magicFlaresCount)
		return;

	shinum++;
	if(shinum >= 10) {
		shinum = 1;
	}
	
	PlatformDuration diff = g_platformTime.lastFrameDuration();
	
	bool key = !GInput->actionPressed(CONTROLS_CUST_MAGICMODE);

	RenderMaterial mat;
	mat.setBlendType(RenderMaterial::Additive);
	
	EERIE_LIGHT * light = lightHandleGet(torchLightHandle);
	
	for(long j = 1; j < 5; j++) {

		TextureContainer * surf;
		switch(j) {
			case 2:  surf = g_magicFlareTextures.lumignon; break;
			case 3:  surf = g_magicFlareTextures.lumignon2; break;
			case 4:  surf = g_magicFlareTextures.plasm; break;
			default: surf = g_magicFlareTextures.shine[shinum]; break;
		}

		mat.setTexture(surf);

		for(size_t i = 0; i < g_magicFlaresMax; i++) {

			MagicFlare & flare = g_magicFlares[i];

			if(!flare.exist || flare.type != j) {
				continue;
			}
			
			flare.tolive -= diff * 2;
			if(flare.flags & 1) {
				flare.tolive -= diff * 4;
			} else if(key) {
				flare.tolive -= diff * 6;
			}
			
			float z = flare.tolive / PlatformDurationMs(4000);
			float size;
			if(flare.type == 1) {
				size = flare.size * 2 * z;
			} else if(flare.type == 4) {
				size = flare.size * 2.f * z * (4.0f / 3.0f);
			} else {
				size = flare.size;
			}

			if(flare.tolive <= 0 || flare.pos.y < -64.f || size < 3.f) {
				removeFlare(flare);
				continue;
			}

			if(flare.type == 1 && z < 0.6f)  {
				z = 0.6f;
			}

			Color3f color = flare.rgb * z;

			light->rgb = componentwise_max(light->rgb, color);
			
			EERIE_LIGHT * el = lightHandleGet(flare.dynlight);
			if(el) {
				el->pos = flare.p;
				el->rgb = color;
			}

			mat.setDepthTest(flare.io != NULL);
			
			if(flare.bDrawBitmap) {
				Vec3f pos = Vec3f(flare.p.x - size / 2.0f, flare.p.y - size / 2.0f, flare.p.z);
				EERIEAddBitmap(mat, pos, size, size, surf, Color(color));
			} else {
				EERIEAddSprite(mat, flare.p, size * 0.025f + 1.f, Color(color), 2.f);
			}

		}
	}

	light->rgb = componentwise_min(light->rgb, Color3f::white);
}