예제 #1
0
//
// R_FindPlane
//
// killough 2/28/98: Add offsets
//
visplane_t *R_FindPlane (plane_t secplane, int picnum, int lightlevel,
						 fixed_t xoffs, fixed_t yoffs,
						 fixed_t xscale, fixed_t yscale, angle_t angle)
{
	visplane_t *check;
	unsigned hash;						// killough

	if (picnum == skyflatnum || picnum & PL_SKYFLAT)  // killough 10/98
		lightlevel = 0;		// most skies map together

	// New visplane algorithm uses hash table -- killough
	hash = visplane_hash (picnum, lightlevel, secplane);

	for (check = visplanes[hash]; check; check = check->next)	// killough
		if (P_IdenticalPlanes(&secplane, &check->secplane) &&
			picnum == check->picnum &&
			lightlevel == check->lightlevel &&
			xoffs == check->xoffs &&	// killough 2/28/98: Add offset checks
			yoffs == check->yoffs &&
			basecolormap == check->colormap &&	// [RH] Add colormap check
			xscale == check->xscale &&
			yscale == check->yscale &&
			angle == check->angle
			)
		  return check;

	check = new_visplane (hash);		// killough

	memcpy(&check->secplane, &secplane, sizeof(secplane));
	check->picnum = picnum;
	check->lightlevel = lightlevel;
	check->xoffs = xoffs;				// killough 2/28/98: Save offsets
	check->yoffs = yoffs;
	check->xscale = xscale;
	check->yscale = yscale;
	check->angle = angle;
	check->colormap = basecolormap;		// [RH] Save colormap
	check->minx = viewwidth;			// Was SCREENWIDTH -- killough 11/98
	check->maxx = -1;

	memset (check->top, 0xff, sizeof(*check->top) * screen->width);

	return check;
}
예제 #2
0
//
// R_AddLine
// Clips the given segment
// and adds any visible pieces to the line list.
//
void R_AddLine (seg_t *line)
{
	curline = line;

	// skip this line if it's not facing the camera
	if (R_PointOnSegSide(viewx, viewy, line) != 0)
		return;

	dcol.color = ((line - segs) & 31) * 4;	// [RH] Color if not texturing line

	// translate the line seg endpoints from world-space to camera-space
	// and store in (t1.x, t1.y) and (t2.x, t2.y)
	v2fixed_t t1, t2;
	R_RotatePoint(line->v1->x - viewx, line->v1->y - viewy, ANG90 - viewangle, t1.x, t1.y);
	R_RotatePoint(line->v2->x - viewx, line->v2->y - viewy, ANG90 - viewangle, t2.x, t2.y);

	// Clip the line seg to the viewing window
	int32_t lclip, rclip;
	if (!R_ClipLineToFrustum(&t1, &t2, NEARCLIP, lclip, rclip))
		return;

	// apply the view frustum clipping to t1 & t2
	R_ClipLine(&t1, &t2, lclip, rclip, &t1, &t2);

	// project the line endpoints to determine which columns the line seg occupies
	int x1 = R_ProjectPointX(t1.x, t1.y);
	int x2 = R_ProjectPointX(t2.x, t2.y) - 1;
	if (!R_CheckProjectionX(x1, x2))
		return;

	rw_start = x1;
	rw_stop = x2;

	// clip the line seg endpoints in world-space
	// and store in (w1.x, w1.y) and (w2.x, w2.y)
	v2fixed_t w1, w2;
	R_ClipLine(line->v1, line->v2, lclip, rclip, &w1, &w2);

	// killough 3/8/98, 4/4/98: hack for invisible ceilings / deep water
	static sector_t tempsec;
	backsector = line->backsector ? R_FakeFlat(line->backsector, &tempsec, NULL, NULL, true) : NULL;

	R_PrepWall(w1.x, w1.y, w2.x, w2.y, t1.y, t2.y, x1, x2);

	// [SL] Check for single-sided line, closed doors or other scenarios that
	// would make this line seg solid.
	//
	// This fixes the automap floor height bug -- killough 1/18/98:
	// killough 4/7/98: optimize: save result in doorclosed for use in r_segs.c

	if (!backsector || !(line->linedef->flags & ML_TWOSIDED) ||
		(rw_backcz1 <= rw_frontfz1 && rw_backcz2 <= rw_frontfz2) ||
		(rw_backfz1 >= rw_frontcz1 && rw_backfz2 >= rw_frontcz2) ||

		// if door is closed because back is shut:
		((rw_backcz1 <= rw_backfz1 && rw_backcz2 <= rw_backfz2) &&
		
		// preserve a kind of transparent door/lift special effect:
		((rw_backcz1 >= rw_frontcz1 && rw_backcz2 >= rw_frontcz2) ||
		 line->sidedef->toptexture) &&
		
		((rw_backfz1 <= rw_frontfz1 && rw_backfz2 <= rw_frontfz2) ||
		 line->sidedef->bottomtexture) &&

		// properly render skies (consider door "open" if both ceilings are sky):
		(backsector->ceilingpic !=skyflatnum || frontsector->ceilingpic!=skyflatnum)))
	{
		doorclosed = true;
		R_ClipWallSegment(x1, x2, true);
		return;
	}

	// Reject empty lines used for triggers and special events.
	// Identical floor and ceiling on both sides,
	// identical light levels on both sides, and no middle texture.
	if (P_IdenticalPlanes(&frontsector->ceilingplane, &backsector->ceilingplane)
		&& P_IdenticalPlanes(&frontsector->floorplane, &backsector->floorplane)
		&& backsector->lightlevel == frontsector->lightlevel
		&& backsector->floorpic == frontsector->floorpic
		&& backsector->ceilingpic == frontsector->ceilingpic
		&& curline->sidedef->midtexture == 0

		// killough 3/7/98: Take flats offsets into account:
		&& backsector->floor_xoffs == frontsector->floor_xoffs
		&& (backsector->floor_yoffs + backsector->base_floor_yoffs) == (frontsector->floor_yoffs + backsector->base_floor_yoffs)
		&& backsector->ceiling_xoffs == frontsector->ceiling_xoffs
		&& (backsector->ceiling_yoffs + backsector->base_ceiling_yoffs) == (frontsector->ceiling_yoffs + frontsector->base_ceiling_yoffs)

		// killough 4/16/98: consider altered lighting
		&& backsector->floorlightsec == frontsector->floorlightsec
		&& backsector->ceilinglightsec == frontsector->ceilinglightsec

		// [RH] Also consider colormaps
		&& backsector->colormap == frontsector->colormap

		// [RH] and scaling
		&& backsector->floor_xscale == frontsector->floor_xscale
		&& backsector->floor_yscale == frontsector->floor_yscale
		&& backsector->ceiling_xscale == frontsector->ceiling_xscale
		&& backsector->ceiling_yscale == frontsector->ceiling_yscale

		// [RH] and rotation
		&& (backsector->floor_angle + backsector->base_floor_angle) == (frontsector->floor_angle + frontsector->base_floor_angle)
		&& (backsector->ceiling_angle + backsector->base_ceiling_angle) == (frontsector->ceiling_angle + frontsector->base_ceiling_angle)
		)
	{
		return;
	}

	doorclosed = false;
	R_ClipWallSegment(x1, x2, false);
}
예제 #3
0
//
// R_AddLine
// Clips the given segment
// and adds any visible pieces to the line list.
//
void R_AddLine (seg_t *line)
{
	int 			x1;
	int 			x2;
	angle_t 		angle1;
	angle_t 		angle2;
	angle_t 		span;
	angle_t 		tspan;
	static sector_t tempsec;	// killough 3/8/98: ceiling/water hack

	curline = line;

	// [RH] Color if not texturing line
	dc_color = ((line - segs) & 31) * 4;

	// OPTIMIZE: quickly reject orthogonal back sides.
	angle1 = R_PointToAngle (line->v1->x, line->v1->y);
	angle2 = R_PointToAngle (line->v2->x, line->v2->y);

	// Clip to view edges.
	// OPTIMIZE: make constant out of 2*clipangle (FIELDOFVIEW).
	span = angle1 - angle2;

	// Back side? I.e. backface culling?
	if (span >= ANG180)
		return;

	// Global angle needed by segcalc.
	rw_angle1 = angle1;
	angle1 -= viewangle;
	angle2 -= viewangle;

	tspan = angle1 + clipangle;
	if (tspan > 2*clipangle)
	{
		// Totally off the left edge?
		if (tspan - 2*clipangle >= span)
			return;

		angle1 = clipangle;
	}
	tspan = clipangle - angle2;
	if (tspan > 2*clipangle)
	{
		// Totally off the left edge?
		if (tspan - 2*clipangle >= span)
			return;
		angle2 = (unsigned) (-(int)clipangle);
	}

	// The seg is in the view range, but not necessarily visible.
	angle1 = (angle1+ANG90)>>ANGLETOFINESHIFT;
	angle2 = (angle2+ANG90)>>ANGLETOFINESHIFT;

	// killough 1/31/98: Here is where "slime trails" can SOMETIMES occur:
	x1 = viewangletox[angle1];
	x2 = viewangletox[angle2];

	// Does not cross a pixel?
	if (x1 >= x2)	// killough 1/31/98 -- change == to >= for robustness
		return;

	rw_start = x1;
	rw_stop = x2 - 1;
	
	rw_frontcz1 = P_CeilingHeight(line->v1->x, line->v1->y, frontsector);
	rw_frontfz1 = P_FloorHeight(line->v1->x, line->v1->y, frontsector);
	rw_frontcz2 = P_CeilingHeight(line->v2->x, line->v2->y, frontsector);
	rw_frontfz2 = P_FloorHeight(line->v2->x, line->v2->y, frontsector);	
	
	backsector = line->backsector;
	// Single sided line?
	if (!backsector)
		goto clipsolid;

	// killough 3/8/98, 4/4/98: hack for invisible ceilings / deep water
	backsector = R_FakeFlat (backsector, &tempsec, NULL, NULL, true);
		
	rw_backcz1 = P_CeilingHeight(line->v1->x, line->v1->y, backsector);
	rw_backfz1 = P_FloorHeight(line->v1->x, line->v1->y, backsector);
	rw_backcz2 = P_CeilingHeight(line->v2->x, line->v2->y, backsector);
	rw_backfz2 = P_FloorHeight(line->v2->x, line->v2->y, backsector);

	// [SL] Check for closed doors or other scenarios that would make this
	// line seg solid.
	//
	// This fixes the automap floor height bug -- killough 1/18/98:
	// killough 4/7/98: optimize: save result in doorclosed for use in r_segs.c
	if (!(line->linedef->flags & ML_TWOSIDED) ||
		 (rw_backcz1 <= rw_frontfz1 && rw_backcz2 <= rw_frontfz2) ||
		 (rw_backfz1 >= rw_frontcz1 && rw_backfz2 >= rw_frontcz2) ||

		// handle a case where the backsector slopes one direction
		// and the frontsector slopes the opposite:
		(rw_backcz1 <= rw_frontfz1 && rw_backfz1 >= rw_frontcz1) ||
		(rw_backcz2 <= rw_frontfz2 && rw_backfz2 >= rw_frontcz2) ||

		// if door is closed because back is shut:
		((rw_backcz1 <= rw_backfz1 && rw_backcz2 <= rw_backfz2) &&
		
		// preserve a kind of transparent door/lift special effect:
		((rw_backcz1 >= rw_frontcz1 && rw_backcz2 >= rw_frontcz2) ||
		 line->sidedef->toptexture) &&
		
		((rw_backfz1 <= rw_frontfz1 && rw_backfz2 <= rw_frontfz2) ||
		 line->sidedef->bottomtexture) &&

		// properly render skies (consider door "open" if both ceilings are sky):
		 (backsector->ceilingpic !=skyflatnum || 
		  frontsector->ceilingpic!=skyflatnum)))
	{
		doorclosed = true;
		goto clipsolid;
	}
	else
	{
		doorclosed = false;
	}

	// Window.
	if (!P_IdenticalPlanes(&frontsector->ceilingplane, &backsector->ceilingplane) ||
		!P_IdenticalPlanes(&frontsector->floorplane, &backsector->floorplane))
		goto clippass;

	// Reject empty lines used for triggers
	//	and special events.
	// Identical floor and ceiling on both sides,
	// identical light levels on both sides,
	// and no middle texture.
	if (backsector->lightlevel == frontsector->lightlevel
		&& backsector->floorpic == frontsector->floorpic
		&& backsector->ceilingpic == frontsector->ceilingpic
		&& curline->sidedef->midtexture == 0

		// killough 3/7/98: Take flats offsets into account:
		&& backsector->floor_xoffs == frontsector->floor_xoffs
		&& (backsector->floor_yoffs + backsector->base_floor_yoffs) == (frontsector->floor_yoffs + backsector->base_floor_yoffs)
		&& backsector->ceiling_xoffs == frontsector->ceiling_xoffs
		&& (backsector->ceiling_yoffs + backsector->base_ceiling_yoffs) == (frontsector->ceiling_yoffs + frontsector->base_ceiling_yoffs)

		// killough 4/16/98: consider altered lighting
		&& backsector->floorlightsec == frontsector->floorlightsec
		&& backsector->ceilinglightsec == frontsector->ceilinglightsec

		// [RH] Also consider colormaps
		&& backsector->floorcolormap == frontsector->floorcolormap
		&& backsector->ceilingcolormap == frontsector->ceilingcolormap

		// [RH] and scaling
		&& backsector->floor_xscale == frontsector->floor_xscale
		&& backsector->floor_yscale == frontsector->floor_yscale
		&& backsector->ceiling_xscale == frontsector->ceiling_xscale
		&& backsector->ceiling_yscale == frontsector->ceiling_yscale

		// [RH] and rotation
		&& (backsector->floor_angle + backsector->base_floor_angle) == (frontsector->floor_angle + frontsector->base_floor_angle)
		&& (backsector->ceiling_angle + backsector->base_ceiling_angle) == (frontsector->ceiling_angle + frontsector->base_ceiling_angle)
		)
	{
		return;
	}

  clippass:
	R_ClipPassWallSegment (x1, x2-1);
	return;

  clipsolid:
	R_ClipSolidWallSegment (x1, x2-1);
}