Exemple #1
0
static void ClipSkyPolygon(int nump, vec3 *vecs, int stage) 
{
	bool front, back;
	float	d, e;
	float	dists[MAX_CLIP_VERTS];
	int		sides[MAX_CLIP_VERTS];
	vec3	newv[2][MAX_CLIP_VERTS];
	int		newc[2];
	int		i, j;

	if (nump > MAX_CLIP_VERTS-2)
		interface::Error("ClipSkyPolygon: MAX_CLIP_VERTS");
	if (stage == 6)
	{	// fully clipped, so draw it
		AddSkyPolygon (nump, vecs);
		return;
	}

	front = back = false;

	for (i=0; i<nump ; i++)
	{
		d = vec3::dotProduct(vecs[i], sky_clip[stage]);
		if (d > ON_EPSILON)
		{
			front = true;
			sides[i] = SIDE_FRONT;
		}
		else if (d < -ON_EPSILON)
		{
			back = true;
			sides[i] = SIDE_BACK;
		}
		else
			sides[i] = SIDE_ON;
		dists[i] = d;
	}

	if (!front || !back)
	{	// not clipped
		ClipSkyPolygon (nump, vecs, stage+1);
		return;
	}

	// clip it
	sides[i] = sides[0];
	dists[i] = dists[0];
	vecs[i] = vecs[0];
	newc[0] = newc[1] = 0;

	for (i=0; i<nump ; i++)
	{
		const vec3 &v = vecs[i];

		switch (sides[i])
		{
		case SIDE_FRONT:
			newv[0][newc[0]] = v;
			newc[0]++;
			break;
		case SIDE_BACK:
			newv[1][newc[1]] = v;
			newc[1]++;
			break;
		case SIDE_ON:
			newv[0][newc[0]] = v;
			newc[0]++;
			newv[1][newc[1]] = v;
			newc[1]++;
			break;
		}

		if (sides[i] == SIDE_ON || sides[i+1] == SIDE_ON || sides[i+1] == sides[i])
			continue;

		d = dists[i] / (dists[i] - dists[i+1]);
		for (j=0 ; j<3 ; j++)
		{
			e = v[j] + d*(vecs[i + 1][j] - v[j]);
			newv[0][newc[0]][j] = e;
			newv[1][newc[1]][j] = e;
		}
		newc[0]++;
		newc[1]++;
	}

	// continue
	ClipSkyPolygon(newc[0], &newv[0][0], stage+1);
	ClipSkyPolygon(newc[1], &newv[1][0], stage+1);
}
Exemple #2
0
/*
================
ClipSkyPolygon
================
*/
static void ClipSkyPolygon (int nump, bvec3_t vecs, int stage) 
{
	bfixed	*norm;
	bfixed	*v;
	qboolean	front, back;
	bfixed	d, e;
	bfixed	dists[MAX_CLIP_VERTS];
	int		sides[MAX_CLIP_VERTS];
	bvec3_t	newv[2][MAX_CLIP_VERTS];
	int		newc[2];
	int		i, j;

	if (nump > MAX_CLIP_VERTS-2)
		ri.Error (ERR_DROP, "ClipSkyPolygon: MAX_CLIP_VERTS");
	if (stage == 6)
	{	// fully clipped, so draw it
		AddSkyPolygon (nump, vecs);
		return;
	}

	front = back = qfalse;
	norm = sky_clip[stage];
	for (i=0, v = vecs ; i<nump ; i++, v+=3)
	{
		d = FIXED_VEC3DOT (v, norm);
		if (d > ON_EPSILON)
		{
			front = qtrue;
			sides[i] = SIDE_FRONT;
		}
		else if (d < -ON_EPSILON)
		{
			back = qtrue;
			sides[i] = SIDE_BACK;
		}
		else
			sides[i] = SIDE_ON;
		dists[i] = d;
	}

	if (!front || !back)
	{	// not clipped
		ClipSkyPolygon (nump, vecs, stage+1);
		return;
	}

	// clip it
	sides[i] = sides[0];
	dists[i] = dists[0];
	VectorCopy (vecs, (vecs+(i*3)) );
	newc[0] = newc[1] = 0;

	for (i=0, v = vecs ; i<nump ; i++, v+=3)
	{
		switch (sides[i])
		{
		case SIDE_FRONT:
			VectorCopy (v, newv[0][newc[0]]);
			newc[0]++;
			break;
		case SIDE_BACK:
			VectorCopy (v, newv[1][newc[1]]);
			newc[1]++;
			break;
		case SIDE_ON:
			VectorCopy (v, newv[0][newc[0]]);
			newc[0]++;
			VectorCopy (v, newv[1][newc[1]]);
			newc[1]++;
			break;
		}

		if (sides[i] == SIDE_ON || sides[i+1] == SIDE_ON || sides[i+1] == sides[i])
			continue;

		d = dists[i] / (dists[i] - dists[i+1]);
		for (j=0 ; j<3 ; j++)
		{
			e = v[j] + d*(v[j+3] - v[j]);
			newv[0][newc[0]][j] = e;
			newv[1][newc[1]][j] = e;
		}
		newc[0]++;
		newc[1]++;
	}

	// continue
	ClipSkyPolygon (newc[0], newv[0][0], stage+1);
	ClipSkyPolygon (newc[1], newv[1][0], stage+1);
}
Exemple #3
0
/*
 * ClipSkyPolygon
 */
static void
ClipSkyPolygon(int nump, Vec3 vecs, int stage)
{
	float *norm;
	float *v;
	qbool		front, back;
	float		d, e;
	float		dists[MAX_CLIP_VERTS];
	int		sides[MAX_CLIP_VERTS];
	Vec3		newv[2][MAX_CLIP_VERTS];
	int		newc[2];
	int		i, j;

	if(nump > MAX_CLIP_VERTS-2)
		ri.Error (ERR_DROP, "ClipSkyPolygon: MAX_CLIP_VERTS");
	if(stage == 6){	/* fully clipped, so draw it */
		AddSkyPolygon (nump, vecs);
		return;
	}

	front	= back = qfalse;
	norm	= sky_clip[stage];
	for(i=0, v = vecs; i<nump; i++, v+=3){
		d = dotv3 (v, norm);
		if(d > ON_EPSILON){
			front = qtrue;
			sides[i] = SIDE_FRONT;
		}else if(d < -ON_EPSILON){
			back = qtrue;
			sides[i] = SIDE_BACK;
		}else
			sides[i] = SIDE_ON;
		dists[i] = d;
	}

	if(!front || !back){	/* not clipped */
		ClipSkyPolygon (nump, vecs, stage+1);
		return;
	}

	/* clip it */
	sides[i] = sides[0];
	dists[i] = dists[0];
	copyv3 (vecs, (vecs+(i*3)));
	newc[0] = newc[1] = 0;

	for(i=0, v = vecs; i<nump; i++, v+=3){
		switch(sides[i]){
		case SIDE_FRONT:
			copyv3 (v, newv[0][newc[0]]);
			newc[0]++;
			break;
		case SIDE_BACK:
			copyv3 (v, newv[1][newc[1]]);
			newc[1]++;
			break;
		case SIDE_ON:
			copyv3 (v, newv[0][newc[0]]);
			newc[0]++;
			copyv3 (v, newv[1][newc[1]]);
			newc[1]++;
			break;
		}

		if(sides[i] == SIDE_ON || sides[i+1] == SIDE_ON || sides[i+1] == sides[i])
			continue;

		d = dists[i] / (dists[i] - dists[i+1]);
		for(j=0; j<3; j++){
			e = v[j] + d*(v[j+3] - v[j]);
			newv[0][newc[0]][j] = e;
			newv[1][newc[1]][j] = e;
		}
		newc[0]++;
		newc[1]++;
	}

	/* continue */
	ClipSkyPolygon (newc[0], newv[0][0], stage+1);
	ClipSkyPolygon (newc[1], newv[1][0], stage+1);
}