// // 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; 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); doorclosed = 0; // killough 4/16/98 // Closed door. if (backsector->ceilingheight <= frontsector->floorheight || backsector->floorheight >= frontsector->ceilingheight) goto clipsolid; // 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 ((doorclosed = R_DoorClosed())) goto clipsolid; // Window. if (backsector->ceilingheight != frontsector->ceilingheight || backsector->floorheight != frontsector->floorheight) 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); }
// // R_AddLine // Clips the given segment and adds any visible pieces to the line list. // static void R_AddLine(seg_t *line) { INT32 x1, x2; angle_t angle1, angle2, span, tspan; static sector_t tempsec; // ceiling/water hack if (line->polyseg && !(line->polyseg->flags & POF_RENDERSIDES)) return; curline = line; // 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. span = angle1 - angle2; // Back side? i.e. backface culling? if (span >= ANGLE_180) return; // Global angle needed by segcalc. rw_angle1 = angle1; angle1 -= viewangle; angle2 -= viewangle; tspan = angle1 + clipangle; if (tspan > doubleclipangle) { tspan -= doubleclipangle; // Totally off the left edge? if (tspan >= span) return; angle1 = clipangle; } tspan = clipangle - angle2; if (tspan > doubleclipangle) { tspan -= doubleclipangle; // Totally off the left edge? if (tspan >= span) return; angle2 = -(signed)clipangle; } // The seg is in the view range, but not necessarily visible. angle1 = (angle1+ANGLE_90)>>ANGLETOFINESHIFT; angle2 = (angle2+ANGLE_90)>>ANGLETOFINESHIFT; x1 = viewangletox[angle1]; x2 = viewangletox[angle2]; // Does not cross a pixel? if (x1 >= x2) // killough 1/31/98 -- change == to >= for robustness return; backsector = line->backsector; // Portal line if (line->linedef->special == 40 && P_PointOnLineSide(viewx, viewy, line->linedef) == 0) { if (portalrender < cv_maxportals.value) { // Find the other side! INT32 line2 = P_FindSpecialLineFromTag(40, line->linedef->tag, -1); if (line->linedef == &lines[line2]) line2 = P_FindSpecialLineFromTag(40, line->linedef->tag, line2); if (line2 >= 0) // found it! { R_AddPortal(line->linedef-lines, line2, x1, x2); // Remember the lines for later rendering //return; // Don't fill in that space now! goto clipsolid; } } // Recursed TOO FAR (viewing a portal within a portal) // So uhhh, render it as a normal wall instead or something ??? } // Single sided line? if (!backsector) goto clipsolid; backsector = R_FakeFlat(backsector, &tempsec, NULL, NULL, true); doorclosed = 0; // Closed door. #ifdef ESLOPE // Just don't bother checking this if one side is sloped. This is probably inefficient, but it's better than // random renderer stopping around slopes... if (!(frontsector->f_slope || frontsector->c_slope || backsector->f_slope || backsector->c_slope)) #endif if (backsector->ceilingheight <= frontsector->floorheight || backsector->floorheight >= frontsector->ceilingheight) { goto clipsolid; } // Check for automap fix. Store in doorclosed for r_segs.c doorclosed = R_DoorClosed(); if (doorclosed) goto clipsolid; // Window. if (backsector->ceilingheight != frontsector->ceilingheight || backsector->floorheight != frontsector->floorheight) { 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 ( #ifdef POLYOBJECTS !line->polyseg && #endif backsector->ceilingpic == frontsector->ceilingpic && backsector->floorpic == frontsector->floorpic #ifdef ESLOPE && backsector->f_slope == frontsector->f_slope && backsector->c_slope == frontsector->c_slope #endif && backsector->lightlevel == frontsector->lightlevel && !curline->sidedef->midtexture // Check offsets too! && backsector->floor_xoffs == frontsector->floor_xoffs && backsector->floor_yoffs == frontsector->floor_yoffs && backsector->floorpic_angle == frontsector->floorpic_angle && backsector->ceiling_xoffs == frontsector->ceiling_xoffs && backsector->ceiling_yoffs == frontsector->ceiling_yoffs && backsector->ceilingpic_angle == frontsector->ceilingpic_angle // Consider altered lighting. && backsector->floorlightsec == frontsector->floorlightsec && backsector->ceilinglightsec == frontsector->ceilinglightsec // Consider colormaps && backsector->extra_colormap == frontsector->extra_colormap && ((!frontsector->ffloors && !backsector->ffloors) || frontsector->tag == backsector->tag)) { return; } clippass: R_ClipPassWallSegment(x1, x2 - 1); return; clipsolid: R_ClipSolidWallSegment(x1, x2 - 1); }
// // R_AddLine // Clips the given segment // and adds any visible pieces to the line list. // static 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; angle1 = R_PointToAngleEx(line->v1->x, line->v1->y); angle2 = R_PointToAngleEx(line->v2->x, line->v2->y); // Clip to view edges. span = angle1 - angle2; // Back side? I.e. backface culling? if (span >= ANG180) return; // Global angle needed by segcalc. angle1 -= viewangle; angle2 -= viewangle; tspan = angle1 + clipangle; if (tspan > 2 * clipangle) { tspan -= 2 * clipangle; // Totally off the left edge? if (tspan >= span) return; angle1 = clipangle; } tspan = clipangle - angle2; if (tspan > 2 * clipangle) { tspan -= 2 * clipangle; // Totally off the left edge? if (tspan >= span) return; angle2 = 0 - 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) return; backsector = line->backsector; // Single sided line? if (!backsector) goto clipsolid; // [AM] Interpolate sector movement before // running clipping tests. Frontsector // should already be interpolated. R_MaybeInterpolateSector(backsector); // killough 3/8/98, 4/4/98: hack for invisible ceilings / deep water backsector = R_FakeFlat(backsector, &tempsec, NULL, NULL, true); doorclosed = false; // killough 4/16/98 // Closed door. if (backsector->interpceilingheight <= frontsector->interpfloorheight || backsector->interpfloorheight >= frontsector->interpceilingheight) goto clipsolid; // 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 ((doorclosed = R_DoorClosed())) goto clipsolid; // Window. if (backsector->interpceilingheight != frontsector->interpceilingheight || backsector->interpfloorheight != frontsector->interpfloorheight) 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->ceilingpic == frontsector->ceilingpic && backsector->floorpic == frontsector->floorpic && backsector->lightlevel == frontsector->lightlevel && !curline->sidedef->midtexture // killough 3/7/98: Take flats offsets into account: && backsector->floor_xoffs == frontsector->floor_xoffs && backsector->floor_yoffs == frontsector->floor_yoffs && backsector->ceiling_xoffs == frontsector->ceiling_xoffs && backsector->ceiling_yoffs == frontsector->ceiling_yoffs // killough 4/16/98: consider altered lighting && backsector->floorlightsec == frontsector->floorlightsec && backsector->ceilinglightsec == frontsector->ceilinglightsec) return; clippass: R_ClipPassWallSegment(x1, x2 - 1); return; clipsolid: R_ClipSolidWallSegment(x1, x2 - 1); }