Exemplo n.º 1
0
/**
 * @brief A follow-up to GatherSampleLight, simply trace along the sun normal, adding sunlight
 */
static void GatherSampleSunlight (const vec3_t pos, const vec3_t normal, float* sample, float* direction, float scale, int* headhint)
{
	vec3_t delta;
	float dot, light;

	if (!sun_intensity)
		return;

	dot = DotProduct(sun_normal, normal);
	if (dot <= 0.001)
		return; /* wrong direction */

	/* don't use only 512 (which would be the 8 level max unit) but a
	 * higher value - because the light angle is not fixed at 90 degree */
	VectorMA(pos, 8192, sun_normal, delta);

	if (TR_TestLineSingleTile(pos, delta, headhint))
		return; /* occluded */

	light = sun_intensity * dot;
	if (light > 255)
		light = 255;
	light *= scale;

	/* add some light to it */
	VectorMA(sample, light, sun_color, sample);

	/* and accumulate the direction */
	VectorMix(normal, sun_normal, light / sun_intensity, delta);
	VectorMA(direction, light * scale, delta, direction);
}
Exemplo n.º 2
0
Blob Scrypt(const ConstBuf& password, const ConstBuf& salt, int n, int r, int p, size_t dkLen) {
	HmacPseudoRandomFunction<SHA256> prf;
	const size_t mfLen = r*128;
	Blob bb = PBKDF2(prf, password, salt, 1, p*mfLen);
	AlignedMem am((n+1)*r*128, 128);
	uint32_t *v = (uint32_t*)am.get();
	SalsaBlockPtr tmp = (SalsaBlockPtr)alloca(r*128);
	for (int i=0; i<p; ++i) {
		SalsaBlockPtr x = (SalsaBlockPtr)(bb.data()+i*mfLen);
		for (int i=0; i<n; ++i) {
			memcpy(&v[i * 32 * r], x, 2*r * sizeof(x[0]));
			VectorMix(Salsa20Core, x, tmp, r, 8);
		}
		for (int i=0; i<n; ++i) {
			int j = 32*r * (x[2 * r - 1][0] & (n - 1));
			VectorXor(x[0], &v[j], 2*r*16);
			VectorMix(Salsa20Core, x, tmp, r, 8);
		}
	}
	return PBKDF2(prf, password, bb, 1, dkLen);
}
Exemplo n.º 3
0
/*
 * S_LoopSample
 */
void S_LoopSample(const vec3_t org, s_sample_t *sample) {
	s_channel_t *ch;
	vec3_t delta;
	int i;

	if (!sample || !sample->chunk)
		return;

	ch = NULL;

	for (i = 0; i < MAX_CHANNELS; i++) { // find existing loop sound

		if (s_env.channels[i].ent_num != -1)
			continue;

		if (s_env.channels[i].sample == sample) {

			VectorSubtract(s_env.channels[i].org, org, delta);

			if (VectorLength(delta) < 512.0) {
				ch = &s_env.channels[i];
				break;
			}
		}
	}

	if (ch) { // update existing loop sample
		ch->count++;

		VectorMix(ch->org, org, 1.0 / ch->count, ch->org);
	} else { // or allocate a new one

		if ((i = S_AllocChannel()) == -1)
			return;

		ch = &s_env.channels[i];

		VectorCopy(org, ch->org);
		ch->ent_num = -1;
		ch->count = 1;
		ch->atten = ATTN_IDLE;
		ch->sample = sample;

		Mix_PlayChannel(i, ch->sample->chunk, 0);
	}

	S_SpatializeChannel(ch);
}
Exemplo n.º 4
0
/**
 * @brief Adds a loop sample for e.g. ambient sounds
 */
void S_LoopSample (const vec3_t org, s_sample_t* sample, float relVolume, float attenuation)
{
	s_channel_t* ch;
	int i;

	if (!sample || !sample->chunk)
		return;

	ch = nullptr;

	for (i = 0; i < MAX_CHANNELS; i++){  /* find existing loop sound */
		if (s_env.channels[i].sample == sample) {
			vec3_t delta;
			VectorSubtract(s_env.channels[i].org, org, delta);
			if (VectorLength(delta) < 255.0) {
				ch = &s_env.channels[i];
				break;
			}
		}
	}

	if (ch) {  /* update existing loop sample */
		ch->count++;

		VectorMix(ch->org, org, 1.0 / ch->count, ch->org);
	} else {  /* or allocate a new one */
		float volume;

		if ((i = S_AllocChannel()) == -1)
			return;

		ch = &s_env.channels[i];

		sample->lastPlayed = CL_Milliseconds();
		VectorCopy(org, ch->org);
		ch->count = 1;
		ch->atten = attenuation;
		ch->sample = sample;

		volume = snd_volume->value * relVolume * MIX_MAX_VOLUME;
		Mix_VolumeChunk(ch->sample->chunk, volume);
		Mix_PlayChannel(i, ch->sample->chunk, 0);
	}

	S_SpatializeChannel(ch);
}
Exemplo n.º 5
0
/*
 * @brief Resolves the surface bounding box and lightmap texture coordinates.
 */
static void R_SetupBspSurface(r_bsp_model_t *bsp, r_bsp_surface_t *surf) {
	vec2_t st_mins, st_maxs;
	uint16_t i, j;

	ClearBounds(surf->mins, surf->maxs);

	st_mins[0] = st_mins[1] = 999999.0;
	st_maxs[0] = st_maxs[1] = -999999.0;

	const r_bsp_texinfo_t *tex = surf->texinfo;

	for (i = 0; i < surf->num_edges; i++) {
		const int32_t e = bsp->surface_edges[surf->first_edge + i];
		const r_bsp_vertex_t *v;

		if (e >= 0)
			v = &bsp->vertexes[bsp->edges[e].v[0]];
		else
			v = &bsp->vertexes[bsp->edges[-e].v[1]];

		AddPointToBounds(v->position, surf->mins, surf->maxs); // calculate mins, maxs

		for (j = 0; j < 2; j++) { // calculate st_mins, st_maxs
			const vec_t val = DotProduct(v->position, tex->vecs[j]) + tex->vecs[j][3];
			if (val < st_mins[j])
				st_mins[j] = val;
			if (val > st_maxs[j])
				st_maxs[j] = val;
		}
	}

	VectorMix(surf->mins, surf->maxs, 0.5, surf->center); // calculate the center

	// bump the texture coordinate vectors to ensure we don't split samples
	for (i = 0; i < 2; i++) {
		const int32_t bmins = floor(st_mins[i] / bsp->lightmaps->scale);
		const int32_t bmaxs = ceil(st_maxs[i] / bsp->lightmaps->scale);

		surf->st_mins[i] = bmins * bsp->lightmaps->scale;
		surf->st_maxs[i] = bmaxs * bsp->lightmaps->scale;

		surf->st_center[i] = (surf->st_maxs[i] + surf->st_mins[i]) / 2.0;
		surf->st_extents[i] = surf->st_maxs[i] - surf->st_mins[i];
	}
}
Exemplo n.º 6
0
/**
 * @brief Adds the specified static light source after first ensuring that it
 * can not be merged with any known sources.
 */
static void R_AddBspLight(r_bsp_model_t *bsp, vec3_t origin, vec3_t color, vec_t radius) {

	if (radius <= 0.0) {
		Com_Debug(DEBUG_RENDERER, "Bad radius: %f\n", radius);
		return;
	}

	if (r_lighting->value) { // scale by r_lighting->value, if enabled
		radius *= r_lighting->value;
	}

	r_bsp_light_t *bl = NULL;
	GSList *e = r_bsp_light_state.lights;
	while (e) {
		vec3_t delta;

		bl = (r_bsp_light_t *) e->data;
		VectorSubtract(origin, bl->light.origin, delta);

		if (VectorLength(delta) <= BSP_LIGHT_MERGE_THRESHOLD) { // merge them
			break;
		}

		bl = NULL;
		e = e->next;
	}

	if (!bl) { // or allocate a new one
		bl = Mem_LinkMalloc(sizeof(*bl), bsp);
		r_bsp_light_state.lights = g_slist_prepend(r_bsp_light_state.lights, bl);

		VectorCopy(origin, bl->light.origin);
		bl->leaf = R_LeafForPoint(bl->light.origin, bsp);
	}

	bl->count++;
	bl->light.radius = ((bl->light.radius * (bl->count - 1)) + radius) / bl->count;

	VectorMix(bl->light.color, color, 1.0 / bl->count, bl->light.color);

	bl->debug.type = PARTICLE_CORONA;
	bl->debug.color[3] = 1.0;
	bl->debug.blend = GL_ONE;
}
Exemplo n.º 7
0
/*
 * R_AddBspLight
 *
 * Adds the specified static light source to the world model, after first
 * ensuring that it can not be merged with any known sources.
 */
static void R_AddBspLight(vec3_t org, float radius, vec3_t color) {
	r_bsp_light_t *l;
	vec3_t delta;
	int i;

	if (radius <= 0.0) {
		Com_Debug("R_AddBspLight: Bad radius: %f\n", radius);
		return;
	}

	l = r_load_model->bsp_lights;
	for (i = 0; i < r_load_model->num_bsp_lights; i++, l++) {

		VectorSubtract(org, l->origin, delta);

		if (VectorLength(delta) <= 32.0) // merge them
			break;
	}

	if (i == r_load_model->num_bsp_lights) { // or allocate a new one

		l = (r_bsp_light_t *) R_HunkAlloc(sizeof(*l));

		if (!r_load_model->bsp_lights) // first source
			r_load_model->bsp_lights = l;

		VectorCopy(org, l->origin);
		l->leaf = R_LeafForPoint(l->origin, r_load_model);

		r_load_model->num_bsp_lights++;
	}

	l->count++;

	l->radius = ((l->radius * (l->count - 1)) + radius) / l->count;

	VectorMix(l->color, color, 1.0 / l->count, l->color);
}
Exemplo n.º 8
0
/**
 * @param[out] sample The sample color
 * @param[in] normal The light direction (normal vector)
 * @param[in] pos The point in the world that receives the light
 * @param[in] scale is the normalizer for multisampling
 * @param[in,out] headhints An array of theads for each light to optimize the tracing
 */
static void GatherSampleLight (vec3_t pos, const vec3_t normal, float* sample, float* direction, float scale, int* headhints)
{
	light_t* l;
	vec3_t delta;
	int* headhint;

	for (l = lights[config.compile_for_day], headhint = headhints; l; l = l->next, headhint++) {
		float light = 0.0;
		float dot2;

		/* Com_Printf("Looking with next hint.\n"); */

		VectorSubtract(l->origin, pos, delta);
		float dist = VectorNormalize(delta);

		float dot = DotProduct(delta, normal);
		if (dot <= 0.001)
			continue;	/* behind sample surface */

		switch (l->type) {
		case emit_point:
			/* linear falloff */
			light = (l->intensity - dist) * dot;
			break;

		case emit_surface:
			/* exponential falloff */
			light = (l->intensity / (dist * dist)) * dot;
			break;

		case emit_spotlight:
			/* linear falloff with cone */
			dot2 = -DotProduct(delta, l->normal);
			if (dot2 > l->stopdot) {
				/* inside the cone */
				light = (l->intensity - dist) * dot;
			} else {
				/* outside the cone */
				light = (l->intensity * (dot2 / l->stopdot) - dist) * dot;
			}
			break;
		default:
			Sys_Error("Bad l->type");
		}

		if (light <= 0.5)  /* almost no light */
			continue;

		if (TR_TestLineSingleTile(pos, l->origin, headhint))
			continue;	/* occluded */

		if (light > 255)
			light = 255;
		/* add some light to it */
		VectorMA(sample, light * scale, l->color, sample);

		/* and add some direction */
		VectorMix(normal, delta, 2.0 * light / l->intensity, delta);
		VectorMA(direction, light * scale, delta, direction);
	}

	/* Com_Printf("Looking with last hint.\n"); */
	GatherSampleSunlight(pos, normal, sample, direction, scale, headhint);
}
Exemplo n.º 9
0
/**
 * @brief Add the indirect lighting on top of the direct
 * lighting and save into final map format
 * @sa BuildFacelights
 */
void FinalLightFace (unsigned int facenum)
{
	int j, k;
	vec3_t dir, intensity;
	byte* dest;

	dBspSurface_t* f = &curTile->faces[facenum];
	facelight_t	*fl = &facelight[config.compile_for_day][facenum];

	/* none-lit texture */
	if (curTile->texinfo[f->texinfo].surfaceFlags & SURF_WARP)
		return;

	ThreadLock();

	f->lightofs[config.compile_for_day] = curTile->lightdatasize[config.compile_for_day];
	curTile->lightdatasize[config.compile_for_day] += fl->numsamples * 3;
	/* account for light direction data as well */
	curTile->lightdatasize[config.compile_for_day] += fl->numsamples * 3;

	if (curTile->lightdatasize[config.compile_for_day] > MAX_MAP_LIGHTING)
		Sys_Error("MAX_MAP_LIGHTING (%i exceeded %i) - try to reduce the brush size (%s)",
			curTile->lightdatasize[config.compile_for_day], MAX_MAP_LIGHTING,
			curTile->texinfo[f->texinfo].texture);

	ThreadUnlock();

	/* write it out */
	dest = &curTile->lightdata[config.compile_for_day][f->lightofs[config.compile_for_day]];

	for (j = 0; j < fl->numsamples; j++) {
		vec3_t temp;

		/* start with raw sample data */
		VectorCopy(fl->samples[j], temp);

		/* convert to float */
		VectorScale(temp, 1.0 / 255.0, temp);

		/* add an ambient term if desired */
		VectorAdd(temp, sun_ambient_color, temp);

		/* apply global scale factor */
		VectorScale(temp, config.brightness, temp);

		float max = 0.0;

		/* find the brightest component */
		for (k = 0; k < 3; k++) {
			/* enforcing positive values */
			if (temp[k] < 0.0)
				temp[k] = 0.0;

			if (temp[k] > max)
				max = temp[k];
		}

		if (max > 255.0)  /* clamp without changing hue */
			VectorScale(temp, 255.0 / max, temp);

		for (k = 0; k < 3; k++) {  /* apply contrast */
			temp[k] -= 0.5;  /* normalize to -0.5 through 0.5 */

			temp[k] *= config.contrast;  /* scale */

			temp[k] += 0.5;

			if (temp[k] > 1.0)  /* clamp */
				temp[k] = 1.0;
			else if (temp[k] < 0)
				temp[k] = 0;
		}

		/* apply saturation */
		float d = DotProduct(temp, luminosity);

		VectorSet(intensity, d, d, d);
		VectorMix(intensity, temp, config.saturation, temp);

		for (k = 0; k < 3; k++) {
			temp[k] *= 255.0;  /* back to byte */

			if (temp[k] > 255.0)  /* clamp */
				temp[k] = 255.0;
			else if (temp[k] < 0.0)
				temp[k] = 0.0;

			*dest++ = (byte)temp[k];
		}

		/* also write the directional data */
		VectorCopy(fl->directions[j], dir);
		for (k = 0; k < 3; k++)
			*dest++ = (byte)((dir[k] + 1.0f) * 127.0f);
	}
}