// // 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; }
// // 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); }
// // 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); }