Exemplo n.º 1
0
// killough 1/28/98: static // CPhipps - const parameter, reformatted
static boolean R_CheckBBox(const fixed_t *bspcoord) 
{
  angle_t angle1, angle2;

  {
    int        boxpos;
    const int* check;
    
    // Find the corners of the box
    // that define the edges from current viewpoint.
    boxpos = (viewx <= bspcoord[BOXLEFT] ? 0 : viewx < bspcoord[BOXRIGHT ] ? 1 : 2) +
      (viewy >= bspcoord[BOXTOP ] ? 0 : viewy > bspcoord[BOXBOTTOM] ? 4 : 8);
    
    if (boxpos == 5)
      return true;
    
    check = checkcoord[boxpos];
    angle1 = R_PointToAngle (bspcoord[check[0]], bspcoord[check[1]]) - viewangle;
    angle2 = R_PointToAngle (bspcoord[check[2]], bspcoord[check[3]]) - viewangle;
  }

  // cph - replaced old code, which was unclear and badly commented
  // Much more efficient code now
  if ((signed)angle1 < (signed)angle2) { /* it's "behind" us */
    /* Either angle1 or angle2 is behind us, so it doesn't matter if we 
     * change it to the corect sign
     */
    if ((angle1 >= ANG180) && (angle1 < ANG270))
      angle1 = INT_MAX; /* which is ANG180-1 */
    else
      angle2 = INT_MIN;
  }

  if ((signed)angle2 >= (signed)clipangle) return false; // Both off left edge
  if ((signed)angle1 <= -(signed)clipangle) return false; // Both off right edge
  if ((signed)angle1 >= (signed)clipangle) angle1 = clipangle; // Clip at left edge
  if ((signed)angle2 <= -(signed)clipangle) angle2 = -clipangle; // Clip at right edge

  // Find the first clippost
  //  that touches the source post
  //  (adjacent pixels are touching).
  angle1 = (angle1+ANG90)>>ANGLETOFINESHIFT;
  angle2 = (angle2+ANG90)>>ANGLETOFINESHIFT;
  {
    int sx1 = viewangletox[angle1];
    int sx2 = viewangletox[angle2];
    //    const cliprange_t *start;

    // Does not cross a pixel.
    if (sx1 == sx2)
      return false;

    if (!memchr(solidcol+sx1, 0, sx2-sx1)) return false; 
    // All columns it covers are already solidly covered
  }

  return true;
}
Exemplo n.º 2
0
Arquivo: r_bsp.c Projeto: jezze/doom
static boolean R_CheckBBox(const fixed_t *bspcoord)
{

    angle_t angle1, angle2;
    int boxpos;
    const int *check;

    boxpos = (viewx <= bspcoord[BOXLEFT] ? 0 : viewx < bspcoord[BOXRIGHT ] ? 1 : 2) + (viewy >= bspcoord[BOXTOP ] ? 0 : viewy > bspcoord[BOXBOTTOM] ? 4 : 8);

    if (boxpos == 5)
        return true;

    check = checkcoord[boxpos];
    angle1 = R_PointToAngle (bspcoord[check[0]], bspcoord[check[1]]) - viewangle;
    angle2 = R_PointToAngle (bspcoord[check[2]], bspcoord[check[3]]) - viewangle;

    if ((signed)angle1 < (signed)angle2)
    {

        if ((angle1 >= ANG180) && (angle1 < ANG270))
            angle1 = INT_MAX;
        else
            angle2 = INT_MIN;

    }

    if ((signed)angle2 >= (signed)clipangle)
        return false;

    if ((signed)angle1 <= -(signed)clipangle)
        return false;

    if ((signed)angle1 >= (signed)clipangle)
        angle1 = clipangle;

    if ((signed)angle2 <= -(signed)clipangle)
        angle2 = 0 - clipangle;

    angle1 = (angle1 + ANG90) >> ANGLETOFINESHIFT;
    angle2 = (angle2 + ANG90) >> ANGLETOFINESHIFT;

    {

        int sx1 = viewangletox[angle1];
        int sx2 = viewangletox[angle2];

        if (sx1 == sx2)
            return false;

        if (!memchr(solidcol + sx1, 0, sx2 - sx1))
            return false;

    }

    return true;

}
Exemplo n.º 3
0
angle_t R_PointToAngle2(fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2)
{
    viewx = x1;
    viewy = y1;

    return R_PointToAngle(x2, y2);
}
Exemplo n.º 4
0
// [BB] Small helper function for MDL_ROLLAGAINSTANGLE.
float gl_RollAgainstAngleHelper ( const AActor *actor )
{
	float angleDiff = ANGLE_TO_FLOAT ( R_PointToAngle ( actor->x, actor->y ) ) - ANGLE_TO_FLOAT ( actor->angle );
	if ( angleDiff > 180 )
		angleDiff -= 360;
	else if ( angleDiff < -180 )
		angleDiff += 360;
	if ( actor->z > viewz )
		angleDiff *= -1;
	if ( ( angleDiff < 90 ) && ( angleDiff > - 90 ) )
		angleDiff *= -1;
	return angleDiff;
}
Exemplo n.º 5
0
bool Clipper::CheckBox(const fixed_t *bspcoord) 
{
	static const int checkcoord[12][4] = // killough -- static const
	{
	  {3,0,2,1},
	  {3,0,2,0},
	  {3,1,2,0},
	  {0},
	  {2,0,2,1},
	  {0,0,0,0},
	  {3,1,3,0},
	  {0},
	  {2,0,3,1},
	  {2,1,3,1},
	  {2,1,3,0}
	};


	angle_t angle1, angle2;

	int        boxpos;
	const int* check;
	
	// Find the corners of the box
	// that define the edges from current viewpoint.
	boxpos = (viewx <= bspcoord[BOXLEFT] ? 0 : viewx < bspcoord[BOXRIGHT ] ? 1 : 2) +
		(viewy >= bspcoord[BOXTOP ] ? 0 : viewy > bspcoord[BOXBOTTOM] ? 4 : 8);
	
	if (boxpos == 5) return true;
	
	check = checkcoord[boxpos];
	angle1 = R_PointToAngle (bspcoord[check[0]], bspcoord[check[1]]);
	angle2 = R_PointToAngle (bspcoord[check[2]], bspcoord[check[3]]);
	
	return SafeCheckRange(angle2, angle1);
}
Exemplo n.º 6
0
void P_BloodSplatter2 (fixed_t x, fixed_t y, fixed_t z, AActor *originator)
{
	if (cl_bloodtype <= 1)
	{
		AActor *mo;
		
		x += ((pr_splat()-128)<<11);
		y += ((pr_splat()-128)<<11);

		mo = Spawn<AAxeBlood> (x, y, z);
		mo->target = originator;
	}
	if (cl_bloodtype >= 1)
	{
		P_DrawSplash2 (100, x, y, z, R_PointToAngle (originator->x - x, originator->y - y), 2, 0);
	}
}
Exemplo n.º 7
0
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
  //  boolean solid = true;

  curline = line;

  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 >= ANG180)
    return;

  // Global angle needed by segcalc.
  rw_angle1 = angle1;
  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 = -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;

  /* cph - roll up linedef properties in flags */
  if ((linedef = curline->linedef)->r_validcount != gametic) 
    R_RecalcLineFlags();

  // Single sided line?
  if (backsector)
    // killough 3/8/98, 4/4/98: hack for invisible ceilings / deep water
    backsector = R_FakeFlat(backsector, &tempsec, NULL, NULL, true);

  if (linedef->r_flags & RF_IGNORE) return;
  else R_ClipWallSegment (x1, x2, linedef->r_flags & RF_CLOSED);
}
Exemplo n.º 8
0
void R_ProjectSprite (mobj_t* thing)
{
  fixed_t   gzt;               // killough 3/27/98
  fixed_t   tx;
  fixed_t   xscale;
  int       x1;
  int       x2;
  spritedef_t   *sprdef;
  spriteframe_t *sprframe;
  int       lump;
  boolean   flip;
  vissprite_t *vis;
  fixed_t   iscale;
  int heightsec;      // killough 3/27/98

  // transform the origin point
  fixed_t tr_x = thing->x - viewx;
  fixed_t tr_y = thing->y - viewy;

  fixed_t gxt = FixedMul(tr_x,viewcos);
  fixed_t gyt = -FixedMul(tr_y,viewsin);

  fixed_t tz = gxt-gyt;

  // thing is behind view plane?
  if (tz < MINZ)
    return;

  // sf: dont draw the object we are viewing through
  // client movement prediction - we can be viewing from player position
  // but outside the body as well

  if(thing == viewobj)
    return;
  
  xscale = FixedDiv(projection, tz);

  gxt = -FixedMul(tr_x,viewsin);
  gyt = FixedMul(tr_y,viewcos);
  tx = -(gyt+gxt);

  // too far off the side?
  if (abs(tx)>(tz<<2))
    return;

    // decide which patch to use for sprite relative to player
  if ((unsigned) thing->sprite >= numsprites)
    {
      C_Printf ("R_ProjectSprite: invalid sprite number %i\n", thing->sprite);
      C_SetConsole();
      return;
    }

  sprdef = &sprites[thing->sprite];

  if ((thing->frame&FF_FRAMEMASK) >= sprdef->numframes)
    I_Error ("R_ProjectSprite:invalid frame %i for sprite %s",
             thing->frame & FF_FRAMEMASK, spritelist[thing->sprite]);

  sprframe = &sprdef->spriteframes[thing->frame & FF_FRAMEMASK];

  if (sprframe->rotate)
    {
      // choose a different rotation based on player view
      angle_t ang = R_PointToAngle(thing->x, thing->y);
      unsigned rot = (ang-thing->angle+(unsigned)(ANG45/2)*9)>>29;
      lump = sprframe->lump[rot];
      flip = (boolean) sprframe->flip[rot];
    }
Exemplo n.º 9
0
boolean R_CheckBBox (fixed_t *bspcoord)
{
	int                     boxx, boxy, boxpos;
	fixed_t         x1, y1, x2, y2;
	angle_t         angle1, angle2, span, tspan;
	cliprange_t     *start;
	int                     sx1, sx2;

#ifdef __NeXT__
	RD_DrawBBox (bspcoord);
#endif

// find the corners of the box that define the edges from current viewpoint
	if (viewx <= bspcoord[BOXLEFT])
		boxx = 0;
	else if (viewx < bspcoord[BOXRIGHT])
		boxx = 1;
	else
		boxx = 2;

	if (viewy >= bspcoord[BOXTOP])
		boxy = 0;
	else if (viewy > bspcoord[BOXBOTTOM])
		boxy = 1;
	else
		boxy = 2;

	boxpos = (boxy<<2)+boxx;
	if (boxpos == 5)
		return true;

	x1 = bspcoord[checkcoord[boxpos][0]];
	y1 = bspcoord[checkcoord[boxpos][1]];
	x2 = bspcoord[checkcoord[boxpos][2]];
	y2 = bspcoord[checkcoord[boxpos][3]];


#ifdef __NeXT__
//      RD_DisplayLine (x1, y1, x2, y2, 0.1);
#endif

//
// check clip list for an open space
//
	angle1 = R_PointToAngle (x1, y1) - viewangle;
	angle2 = R_PointToAngle (x2, y2) - viewangle;

	span = angle1 - angle2;
	if (span >= ANG180)
		return true;    // sitting on a line
	tspan = angle1 + clipangle;
	if (tspan > 2*clipangle)
	{
		tspan -= 2*clipangle;
		if (tspan >= span)
			return false;   // totally off the left edge
		angle1 = clipangle;
	}
	tspan = clipangle - angle2;
	if (tspan > 2*clipangle)
	{
		tspan -= 2*clipangle;
		if (tspan >= span)
			return false;   // totally off the left edge
		angle2 = -clipangle;
	}


// find the first clippost that touches the source post (adjacent pixels are touching)
	angle1 = (angle1+ANG90)>>ANGLETOFINESHIFT;
	angle2 = (angle2+ANG90)>>ANGLETOFINESHIFT;
	sx1 = viewangletox[angle1];
	sx2 = viewangletox[angle2];
	if (sx1 == sx2)
		return false;                           // does not cross a pixel
	sx2--;

	start = solidsegs;
	while (start->last < sx2)
		start++;
	if (sx1 >= start->first && sx2 <= start->last)
		return false;   // the clippost contains the new span

	return true;
}
Exemplo n.º 10
0
void R_AddLine (seg_t *line)
{
	int                     x1, x2;
	angle_t         angle1, angle2, span, tspan;

#ifdef __NeXT__
	RD_DrawLineCheck (line);
#endif
	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
// OPTIMIZE: make constant out of 2*clipangle (FIELDOFVIEW)
	span = angle1 - angle2;
	if (span >= ANG180)
		return;         // back side

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

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

//
// the seg is in the view range, but not necessarily visible
//
	angle1 = (angle1+ANG90)>>ANGLETOFINESHIFT;
	angle2 = (angle2+ANG90)>>ANGLETOFINESHIFT;
	x1 = viewangletox[angle1];
	x2 = viewangletox[angle2];
	if (x1 == x2)
		return;                         // does not cross a pixel

	backsector = line->backsector;

	if (!backsector)
		goto clipsolid;         // single sided line

	if (backsector->ceilingheight <= frontsector->floorheight
	|| backsector->floorheight >= frontsector->ceilingheight)
		goto clipsolid;         // closed door

	if (backsector->ceilingheight != frontsector->ceilingheight
	|| backsector->floorheight != frontsector->floorheight)
		goto clippass;          // window

// reject empty lines used for triggers and special events
	if (backsector->ceilingpic == frontsector->ceilingpic
	&& backsector->floorpic == frontsector->floorpic
	&& backsector->lightlevel == frontsector->lightlevel
	&& backsector->special == frontsector->special
	&& curline->sidedef->midtexture == 0)
		return;

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

clipsolid:
	R_ClipSolidWallSegment (x1, x2-1);
}
Exemplo n.º 11
0
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_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 >= ANG180)
    return;

  // Global angle needed by segcalc.
  rw_angle1 = angle1;
  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];

#ifdef GL_DOOM
  // proff 11/99: we have to add these segs to avoid gaps in OpenGL
  if (x1 >= x2)       // killough 1/31/98 -- change == to >= for robustness
  {
    if (V_GetMode() == VID_MODEGL)
    {
      if (ds_p == drawsegs+maxdrawsegs)   // killough 1/98 -- fix 2s line HOM
      {
        unsigned pos = ds_p - drawsegs; // jff 8/9/98 fix from ZDOOM1.14a
        unsigned newmax = maxdrawsegs ? maxdrawsegs*2 : 128; // killough
        drawsegs = realloc(drawsegs,newmax*sizeof(*drawsegs));
        //ds_p = drawsegs+maxdrawsegs;
        ds_p = drawsegs + pos;          // jff 8/9/98 fix from ZDOOM1.14a
        maxdrawsegs = newmax;
      }
      ds_p->curline = curline;
      ds_p++;
      gld_AddWall(curline);
      return;
    }
    else
      return;
  }
#else
  // Does not cross a pixel?
  if (x1 >= x2)       // killough 1/31/98 -- change == to >= for robustness
    return;
#endif

  backsector = line->backsector;

  // Single sided line?
  if (backsector)
    // killough 3/8/98, 4/4/98: hack for invisible ceilings / deep water
    backsector = R_FakeFlat(backsector, &tempsec, NULL, NULL, true);

  /* cph - roll up linedef properties in flags */
  if ((linedef = curline->linedef)->r_validcount != gametic)
    R_RecalcLineFlags();

  if (linedef->r_flags & RF_IGNORE)
  {
    return;
  }
  else
    R_ClipWallSegment (x1, x2, linedef->r_flags & RF_CLOSED);
}
Exemplo n.º 12
0
static boolean R_CheckBBox(fixed_t *bspcoord)
{
	INT32 boxpos, sx1, sx2;
	fixed_t px1, py1, px2, py2;
	angle_t angle1, angle2, span, tspan;
	cliprange_t *start;

	// Find the corners of the box that define the edges from current viewpoint.
	if (viewx <= bspcoord[BOXLEFT])
		boxpos = 0;
	else if (viewx < bspcoord[BOXRIGHT])
		boxpos = 1;
	else
		boxpos = 2;

	if (viewy >= bspcoord[BOXTOP])
		boxpos |= 0;
	else if (viewy > bspcoord[BOXBOTTOM])
		boxpos |= 1<<2;
	else
		boxpos |= 2<<2;

	if (boxpos == 5)
		return true;

	px1 = bspcoord[checkcoord[boxpos][0]];
	py1 = bspcoord[checkcoord[boxpos][1]];
	px2 = bspcoord[checkcoord[boxpos][2]];
	py2 = bspcoord[checkcoord[boxpos][3]];

	// check clip list for an open space
	angle1 = R_PointToAngle(px1, py1) - viewangle;
	angle2 = R_PointToAngle(px2, py2) - viewangle;

	span = angle1 - angle2;

	// Sitting on a line?
	if (span >= ANGLE_180)
		return true;

	tspan = angle1 + clipangle;

	if (tspan > doubleclipangle)
	{
		tspan -= doubleclipangle;

		// Totally off the left edge?
		if (tspan >= span)
			return false;

		angle1 = clipangle;
	}
	tspan = clipangle - angle2;
	if (tspan > doubleclipangle)
	{
		tspan -= doubleclipangle;

		// Totally off the left edge?
		if (tspan >= span)
			return false;

		angle2 = -(signed)clipangle;
	}

	// Find the first clippost that touches the source post (adjacent pixels are touching).
	angle1 = (angle1+ANGLE_90)>>ANGLETOFINESHIFT;
	angle2 = (angle2+ANGLE_90)>>ANGLETOFINESHIFT;
	sx1 = viewangletox[angle1];
	sx2 = viewangletox[angle2];

	// Does not cross a pixel.
	if (sx1 == sx2)
		return false;
	sx2--;

	start = solidsegs;
	while (start->last < sx2)
		start++;

	if (sx1 >= start->first && sx2 <= start->last)
		return false; // The clippost contains the new span.

	return true;
}
Exemplo n.º 13
0
boolean R_CheckBBox (fixed_t*	bspcoord)
{
    int			boxx;
    int			boxy;
    int			boxpos;

    fixed_t		x1;
    fixed_t		y1;
    fixed_t		x2;
    fixed_t		y2;
    
    angle_t		angle1;
    angle_t		angle2;
    angle_t		span;
    angle_t		tspan;
    
    cliprange_t*	start;

    int			sx1;
    int			sx2;
    
    // Find the corners of the box
    // that define the edges from current viewpoint.
    if (viewx <= bspcoord[BOXLEFT])
	boxx = 0;
    else if (viewx < bspcoord[BOXRIGHT])
	boxx = 1;
    else
	boxx = 2;
		
    if (viewy >= bspcoord[BOXTOP])
	boxy = 0;
    else if (viewy > bspcoord[BOXBOTTOM])
	boxy = 1;
    else
	boxy = 2;
		
    boxpos = (boxy<<2)+boxx;
    if (boxpos == 5)
	return true;
	
    x1 = bspcoord[checkcoord[boxpos][0]];
    y1 = bspcoord[checkcoord[boxpos][1]];
    x2 = bspcoord[checkcoord[boxpos][2]];
    y2 = bspcoord[checkcoord[boxpos][3]];
    
    // check clip list for an open space
    angle1 = R_PointToAngle (x1, y1) - viewangle;
    angle2 = R_PointToAngle (x2, y2) - viewangle;
	
    span = angle1 - angle2;

    // Sitting on a line?
    if (span >= ANG180)
	return true;
    
    tspan = angle1 + clipangle;

    if (tspan > 2*clipangle)
    {
	tspan -= 2*clipangle;

	// Totally off the left edge?
	if (tspan >= span)
	    return false;	

	angle1 = clipangle;
    }
    tspan = clipangle - angle2;
    if (tspan > 2*clipangle)
    {
	tspan -= 2*clipangle;

	// Totally off the left edge?
	if (tspan >= span)
	    return false;
	
	angle2 = -clipangle;
    }


    // Find the first clippost
    //  that touches the source post
    //  (adjacent pixels are touching).
    angle1 = (angle1+ANG90)>>ANGLETOFINESHIFT;
    angle2 = (angle2+ANG90)>>ANGLETOFINESHIFT;
    sx1 = viewangletox[angle1];
    sx2 = viewangletox[angle2];

    // Does not cross a pixel.
    if (sx1 == sx2)
	return false;			
    sx2--;
	
    start = solidsegs;
    while (start->last < sx2)
	start++;
    
    if (sx1 >= start->first
	&& sx2 <= start->last)
    {
	// The clippost contains the new span.
	return false;
    }

    return true;
}
Exemplo n.º 14
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;
    
    curline = line;

    // OPTIMIZE: quickly reject orthogonal back sides.
    // [crispy] remove slime trails
    angle1 = R_PointToAngle (line->v1->px, line->v1->py);
    angle2 = R_PointToAngle (line->v2->px, line->v2->py);
    
    // 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)
    {
	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 = -clipangle;
    }
    
    // The seg is in the view range,
    // but not necessarily visible.
    angle1 = (angle1+ANG90)>>ANGLETOFINESHIFT;
    angle2 = (angle2+ANG90)>>ANGLETOFINESHIFT;
    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);

    // Closed door.
    if (backsector->interpceilingheight <= frontsector->interpfloorheight
	|| backsector->interpfloorheight >= frontsector->interpceilingheight)
	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 == 0)
    {
	return;
    }
    
				
  clippass:
    R_ClipPassWallSegment (x1, x2-1);	
    return;
		
  clipsolid:
    R_ClipSolidWallSegment (x1, x2-1);
}
Exemplo n.º 15
0
void gl_RenderModel(GLSprite * spr, int cm)
{
	// [BB/EP] Take care of gl_fogmode and ZADF_FORCE_GL_DEFAULTS.
	OVERRIDE_FOGMODE_IF_NECESSARY

	FSpriteModelFrame * smf = spr->modelframe;


	// Setup transformation.
	gl.MatrixMode(GL_MODELVIEW);
	gl.PushMatrix();
	gl.DepthFunc(GL_LEQUAL);
	// [BB] In case the model should be rendered translucent, do back face culling.
	// This solves a few of the problems caused by the lack of depth sorting.
	// TO-DO: Implement proper depth sorting.
	if (!( spr->actor->RenderStyle == LegacyRenderStyles[STYLE_Normal] ))
	{
		gl.Enable(GL_CULL_FACE);
		glFrontFace(GL_CW);
	}

	int translation = 0;
	if ( !(smf->flags & MDL_IGNORETRANSLATION) )
		translation = spr->actor->Translation;


	// y scale for a sprite means height, i.e. z in the world!
	float scaleFactorX = FIXED2FLOAT(spr->actor->scaleX) * smf->xscale;
	float scaleFactorY = FIXED2FLOAT(spr->actor->scaleX) * smf->yscale;
	float scaleFactorZ = FIXED2FLOAT(spr->actor->scaleY) * smf->zscale;
	float pitch = 0;
	float rotateOffset = 0;
	float angle = ANGLE_TO_FLOAT(spr->actor->angle);

	// [BB] Workaround for the missing pitch information.
	if ( (smf->flags & MDL_PITCHFROMMOMENTUM) )
	{
		const double x = static_cast<double>(spr->actor->velx);
		const double y = static_cast<double>(spr->actor->vely);
		const double z = static_cast<double>(spr->actor->velz);
		// [BB] Calculate the pitch using spherical coordinates.
		
		pitch = float(atan( z/sqrt(x*x+y*y) ) / M_PI * 180);
	}

	if( smf->flags & MDL_ROTATING )
	{
		const float time = smf->rotationSpeed*GetTimeFloat()/200.f;
		rotateOffset = float((time - xs_FloorToInt(time)) *360.f );
	}

	if (gl_fogmode != 2 && (GLRenderer->mLightCount == 0 || !gl_light_models))
	{
		// Model space => World space
		gl.Translatef(spr->x, spr->z, spr->y );

		if ( !(smf->flags & MDL_ALIGNANGLE) )
			gl.Rotatef(-angle, 0, 1, 0);
		// [BB] Change the angle so that the object is exactly facing the camera in the x/y plane.
		else
			gl.Rotatef( -ANGLE_TO_FLOAT ( R_PointToAngle ( spr->actor->x, spr->actor->y ) ), 0, 1, 0);

		// [BB] Change the pitch so that the object is vertically facing the camera (only makes sense combined with MDL_ALIGNANGLE).
		if ( (smf->flags & MDL_ALIGNPITCH) )
		{
			const fixed_t distance = R_PointToDist2( spr->actor->x - viewx, spr->actor->y - viewy );
			const float pitch = RAD2DEG ( atan2( FIXED2FLOAT ( spr->actor->z - viewz ), FIXED2FLOAT ( distance ) ) );
			gl.Rotatef(pitch, 0, 0, 1);
		}

		// [BB] Workaround for the missing pitch information.
		if (pitch != 0)	gl.Rotatef(pitch, 0, 0, 1);

		// [BB] Special flag for flat, beam like models.
		if ( (smf->flags & MDL_ROLLAGAINSTANGLE) )
			gl.Rotatef( gl_RollAgainstAngleHelper ( spr->actor ), 1, 0, 0);

		// Model rotation.
		// [BB] Added Doomsday like rotation of the weapon pickup models.
		// The rotation angle is based on the elapsed time.

		if( smf->flags & MDL_ROTATING )
		{
			gl.Translatef(smf->rotationCenterX, smf->rotationCenterY, smf->rotationCenterZ);
			gl.Rotatef(rotateOffset, smf->xrotate, smf->yrotate, smf->zrotate);
			gl.Translatef(-smf->rotationCenterX, -smf->rotationCenterY, -smf->rotationCenterZ);
		} 		

		// Scaling and model space offset.
		gl.Scalef(scaleFactorX, scaleFactorZ, scaleFactorY);

		// [BB] Apply zoffset here, needs to be scaled by 1 / smf->zscale, so that zoffset doesn't depend on the z-scaling.
		gl.Translatef(0., smf->zoffset / smf->zscale, 0.);

		gl_RenderFrameModels( smf, spr->actor->state, spr->actor->tics, RUNTIME_TYPE(spr->actor), cm, NULL, NULL, translation );
	}
	else
	{
		Matrix3x4 ModelToWorld;
		Matrix3x4 NormalTransform;

		// For radial fog we need to pass coordinates in world space in order to calculate distances.
		// That means that the local transformations cannot be part of the modelview matrix

		ModelToWorld.MakeIdentity();

		// Model space => World space
		ModelToWorld.Translate(spr->x, spr->z, spr->y);

		if ( !(smf->flags & MDL_ALIGNANGLE) )
			ModelToWorld.Rotate(0,1,0, -angle);
		// [BB] Change the angle so that the object is exactly facing the camera in the x/y plane.
		else
			ModelToWorld.Rotate(0,1,0, -ANGLE_TO_FLOAT ( R_PointToAngle ( spr->actor->x, spr->actor->y ) ) );

		// [BB] Change the pitch so that the object is vertically facing the camera (only makes sense combined with MDL_ALIGNANGLE).
		if ( (smf->flags & MDL_ALIGNPITCH) )
		{
			const fixed_t distance = R_PointToDist2( spr->actor->x - viewx, spr->actor->y - viewy );
			const float pitch = RAD2DEG ( atan2( FIXED2FLOAT ( spr->actor->z - viewz ), FIXED2FLOAT ( distance ) ) );
			ModelToWorld.Rotate(0,0,1,pitch);
		}

		// [BB] Workaround for the missing pitch information.
		if (pitch != 0) ModelToWorld.Rotate(0,0,1,pitch);

		// [BB] Special flag for flat, beam like models.
		if ( (smf->flags & MDL_ROLLAGAINSTANGLE) )
			ModelToWorld.Rotate(1, 0, 0, gl_RollAgainstAngleHelper ( spr->actor ));

		// Model rotation.
		// [BB] Added Doomsday like rotation of the weapon pickup models.
		// The rotation angle is based on the elapsed time.

		if( smf->flags & MDL_ROTATING )
		{
			ModelToWorld.Translate(-smf->rotationCenterX, -smf->rotationCenterY, -smf->rotationCenterZ);
			ModelToWorld.Rotate(smf->xrotate, smf->yrotate, smf->zrotate, rotateOffset);
			ModelToWorld.Translate(smf->rotationCenterX, smf->rotationCenterY, smf->rotationCenterZ);
		}

		ModelToWorld.Scale(scaleFactorX, scaleFactorZ, scaleFactorY);

		// [BB] Apply zoffset here, needs to be scaled by 1 / smf->zscale, so that zoffset doesn't depend on the z-scaling.
		ModelToWorld.Translate(0., smf->zoffset / smf->zscale, 0.);

		if (!gl_light_models)
		{
			gl_RenderFrameModels( smf, spr->actor->state, spr->actor->tics, RUNTIME_TYPE(spr->actor), cm, &ModelToWorld, NULL, translation );
		}
		else
		{
			// The normal transform matrix only contains the inverse rotations and scalings but not the translations
			NormalTransform.MakeIdentity();

			NormalTransform.Scale(1.f/scaleFactorX, 1.f/scaleFactorZ, 1.f/scaleFactorY);
			if( smf->flags & MDL_ROTATING ) NormalTransform.Rotate(smf->xrotate, smf->yrotate, smf->zrotate, -rotateOffset);
			if (pitch != 0) NormalTransform.Rotate(0,0,1,-pitch);
			if (angle != 0) NormalTransform.Rotate(0,1,0, angle);

			gl_RenderFrameModels( smf, spr->actor->state, spr->actor->tics, RUNTIME_TYPE(spr->actor), cm, &ModelToWorld, &NormalTransform, translation );
		}

	}

	gl.MatrixMode(GL_MODELVIEW);
	gl.PopMatrix();
	gl.DepthFunc(GL_LESS);
	if (!( spr->actor->RenderStyle == LegacyRenderStyles[STYLE_Normal] ))
		gl.Disable(GL_CULL_FACE);
}
Exemplo n.º 16
0
//
// 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;
	portalline = false;

	// 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 && line->side == 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
	if (frontsector->f_slope || frontsector->c_slope || backsector->f_slope || backsector->c_slope)
	{
		fixed_t frontf1,frontf2, frontc1, frontc2; // front floor/ceiling ends
		fixed_t backf1, backf2, backc1, backc2; // back floor ceiling ends
#define SLOPEPARAMS(slope, end1, end2, normalheight) \
		if (slope) { \
			end1 = P_GetZAt(slope, line->v1->x, line->v1->y); \
			end2 = P_GetZAt(slope, line->v2->x, line->v2->y); \
		} else \
			end1 = end2 = normalheight;

		SLOPEPARAMS(frontsector->f_slope, frontf1, frontf2, frontsector->floorheight)
		SLOPEPARAMS(frontsector->c_slope, frontc1, frontc2, frontsector->ceilingheight)
		SLOPEPARAMS( backsector->f_slope, backf1,  backf2,  backsector->floorheight)
		SLOPEPARAMS( backsector->c_slope, backc1,  backc2,  backsector->ceilingheight)
#undef SLOPEPARAMS
		if ((backc1 <= frontf1 && backc2 <= frontf2)
			|| (backf1 >= frontc1 && backf2 >= frontc2))
		{
			goto clipsolid;
		}

		// Check for automap fix. Store in doorclosed for r_segs.c
		doorclosed = (backc1 <= backf1 && backc2 <= backf2
		&& ((backc1 >= frontc1 && backc2 >= frontc2) || curline->sidedef->toptexture)
		&& ((backf1 <= frontf1 && backf2 >= frontf2) || curline->sidedef->bottomtexture)
		&& (backsector->ceilingpic != skyflatnum || frontsector->ceilingpic != skyflatnum));

		if (doorclosed)
			goto clipsolid;

		// Window.
		if (backc1 != frontc1 || backc2 != frontc2
			|| backf1 != frontf1 || backf2 != frontf2)
		{
			goto clippass;
		}
	}
Exemplo n.º 17
0
static dboolean R_CheckBBox(const fixed_t *bspcoord)
{
    int         boxpos;
    const int   *check;

    angle_t     angle1;
    angle_t     angle2;

    cliprange_t *start;

    int         sx1;
    int         sx2;

    // Find the corners of the box
    // that define the edges from current viewpoint.
    boxpos = (viewx <= bspcoord[BOXLEFT] ? 0 : viewx < bspcoord[BOXRIGHT ] ? 1 : 2) +
             (viewy >= bspcoord[BOXTOP ] ? 0 : viewy > bspcoord[BOXBOTTOM] ? 4 : 8);

    if (boxpos == 5)
        return true;

    check = checkcoord[boxpos];

    // check clip list for an open space
    angle1 = R_PointToAngle(bspcoord[check[0]], bspcoord[check[1]]) - viewangle;
    angle2 = R_PointToAngle(bspcoord[check[2]], bspcoord[check[3]]) - viewangle;

    // cph - replaced old code, which was unclear and badly commented
    // Much more efficient code now
    if ((signed int)angle1 < (signed int)angle2)
    {
        // Either angle1 or angle2 is behind us, so it doesn't matter if we
        // change it to the correct sign
        if (angle1 >= ANG180 && angle1 < ANG270)
            angle1 = INT_MAX;           // which is ANG180 - 1
        else
            angle2 = INT_MIN;
    }

    if ((signed int)angle2 >= (signed int)clipangle)
        return false;                   // Both off left edge
    if ((signed int)angle1 <= -(signed int)clipangle)
        return false;                   // Both off right edge
    if ((signed int)angle1 >= (signed int)clipangle)
        angle1 = clipangle;             // Clip at left edge
    if ((signed int)angle2 <= -(signed int)clipangle)
        angle2 = 0 - clipangle;         // Clip at right edge

    // Find the first clippost
    //  that touches the source post
    //  (adjacent pixels are touching).
    angle1 = (angle1 + ANG90) >> ANGLETOFINESHIFT;
    angle2 = (angle2 + ANG90) >> ANGLETOFINESHIFT;
    sx1 = viewangletox[angle1];
    sx2 = viewangletox[angle2];

    // SoM: To account for the rounding error of the old BSP system, I needed to
    // make adjustments.
    // SoM: Moved this to before the "does not cross a pixel" check to fix
    // another slime trail
    if (sx1 > 0)
        sx1--;
    if (sx2 < viewwidth - 1)
        sx2++;

    // SoM: Removed the "does not cross a pixel" test

    start = solidsegs;
    while (start->last < sx2)
        ++start;

    if (sx1 >= start->first && sx2 <= start->last)
        return false;                   // The clippost contains the new span.

    return true;
}
Exemplo n.º 18
0
Arquivo: r_bsp.c Projeto: jezze/doom
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;

    curline = line;
    angle1 = R_PointToAngle(line->v1->x, line->v1->y);
    angle2 = R_PointToAngle(line->v2->x, line->v2->y);
    span = angle1 - angle2;

    if (span >= ANG180)
        return;

    rw_angle1 = angle1;
    angle1 -= viewangle;
    angle2 -= viewangle;
    tspan = angle1 + clipangle;

    if (tspan > 2 * clipangle)
    {

        tspan -= 2 * clipangle;

        if (tspan >= span)
            return;

        angle1 = clipangle;

    }

    tspan = clipangle - angle2;

    if (tspan > 2 * clipangle)
    {

        tspan -= 2 * clipangle;

        if (tspan >= span)
            return;

        angle2 = 0-clipangle;

    }

    angle1 = (angle1 + ANG90) >> ANGLETOFINESHIFT;
    angle2 = (angle2 + ANG90) >> ANGLETOFINESHIFT;
    x1 = viewangletox[angle1];
    x2 = viewangletox[angle2];

    if (x1 >= x2)
        return;

    backsector = line->backsector;

    if (backsector)
        backsector = R_FakeFlat(backsector, &tempsec, NULL, NULL, true);

    if ((linedef = curline->linedef)->r_validcount != gametic)
        R_RecalcLineFlags();

    if (linedef->r_flags & RF_IGNORE)
        return;
    else
        R_ClipWallSegment (x1, x2, linedef->r_flags & RF_CLOSED);

}
Exemplo n.º 19
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);
}
Exemplo n.º 20
0
//
// R_AddLine
// Clips the given segment
// and adds any visible pieces to the line list.
//
void R_AddLine(seg_t* line, vector<SegInfo>& segInfo, int parentIdx)
{
	int			x1;
	int			x2;
	angle_t		angle1;
	angle_t		angle2;
	angle_t		span;
	angle_t		tspan;

	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.
	// 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)
	{
		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 = -static_cast<int>(clipangle);
	}

	// The seg is in the view range,
	// but not necessarily visible.
	angle1 = (angle1 + ANG90) >> ANGLETOFINESHIFT;
	angle2 = (angle2 + ANG90) >> ANGLETOFINESHIFT;
	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;

	// Closed door.
	if (backsector->ceilingheight <= frontsector->floorheight
		|| backsector->floorheight >= frontsector->ceilingheight)
		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->ceilingpic == frontsector->ceilingpic
		&& backsector->floorpic == frontsector->floorpic
		&& backsector->lightlevel == frontsector->lightlevel
		&& curline->sidedef->midtexture == 0)
	{
		return;
	}


clippass:
	AddSegInfo(line, segInfo, parentIdx);
	R_ClipPassWallSegment(x1, x2 - 1);
	return;

clipsolid:
	AddSegInfo(line, segInfo, parentIdx);
	R_ClipSolidWallSegment(x1, x2 - 1);
}
Exemplo n.º 21
0
Arquivo: r_bsp.c Projeto: Yukitty/SRB2
//
// 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);
}
Exemplo n.º 22
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;

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