p_sight.c
/*
=================
=
= PS_CrossSubsector
=
= Returns true if strace crosses the given subsector successfuly
=================
*/
PS_CrossSubsector
Returns true if strace crosses the given subsector successfuly
PS_CrossSubsector Returns true if strace crosses the given subsector successfuly
static boolean PS_CrossSubsector(sightWork_t *sw, int num)
{
   seg_t       *seg;
   line_t      *line;
   int          s1;
   int          s2;
   int          count;
   subsector_t *sub;
   sector_t    *front;
   sector_t    *back;
   fixed_t      opentop;
   fixed_t      openbottom;
   divline_t    divl;
   vertex_t    *v1;
   vertex_t    *v2;
   fixed_t      frac;
   fixed_t      slope;
   int          side;
   divline_t    *strace = &sw->strace;
   fixed_t      t2x = sw->t2x, t2y = sw->t2y;
   fixed_t      sightzstart = sw->sightzstart;
   sub = &subsectors[num];
   count = sub->numlines;
   seg   = &segs[sub->firstline];
   for( ; count; seg++, count--)
   {
      line = seg->linedef;
      if(line->validcount == validcount)
         continue;
      line->validcount = validcount;
      v1 = line->v1;
      v2 = line->v2;
      s1 = P_DivlineSide(v1->x, v1->y, strace);
      s2 = P_DivlineSide(v2->x, v2->y, strace);
      if (s1 == s2)
         continue;
      divl.x = v1->x;
      divl.y = v1->y;
      divl.dx = v2->x - v1->x;
      divl.dy = v2->y - v1->y;
      s1 = P_DivlineSide (strace->x, strace->y, &divl);
      s2 = P_DivlineSide (t2x, t2y, &divl);
      if (s1 == s2)
         continue;
      if(!(line->flags & ML_TWOSIDED))
         return false;
      side = seg->side;
      front = &sectors[sides[line->sidenum[side]].sector];
      back = (line->flags & ML_TWOSIDED) ? &sectors[sides[line->sidenum[side^1]].sector] : 0;
      if(front->floorheight == back->floorheight && front->ceilingheight == back->ceilingheight)
         continue;
      if (front->ceilingheight < back->ceilingheight)
         opentop = front->ceilingheight;
      else
         opentop = back->ceilingheight;
      if (front->floorheight > back->floorheight)
         openbottom = front->floorheight;
      else
         openbottom = back->floorheight;
      if(openbottom >= opentop)
         return false; 
      frac = P_InterceptVector2(strace, &divl);
      if(front->floorheight != back->floorheight)
      {
         slope = FixedDiv(openbottom - sightzstart , frac);
         if(slope > sw->bottomslope)
             sw->bottomslope = slope;
      }
      if(front->ceilingheight != back->ceilingheight)
      {
         slope = FixedDiv (opentop - sightzstart , frac);
         if(slope < sw->topslope)
             sw->topslope = slope;
      }
      if(sw->topslope <= sw->bottomslope)
         return false;    
   }
   return true;
}
static boolean PS_CrossSubsector ( sightWork_t * sw , int num ) { seg_t * seg ; line_t * line ; int s1 ; int s2 ; int count ; subsector_t * sub ; sector_t * front ; sector_t * back ; fixed_t opentop ; fixed_t openbottom ; divline_t divl ; vertex_t * v1 ; vertex_t * v2 ; fixed_t frac ; fixed_t slope ; int side ; divline_t * strace = & sw -> strace ; fixed_t t2x = sw -> t2x , t2y = sw -> t2y ; fixed_t sightzstart = sw -> sightzstart ; sub = & subsectors [ num ] ; count = sub -> numlines ; seg = & segs [ sub -> firstline ] ; for ( ; count ; seg ++ , count -- ) { line = seg -> linedef ; if ( line -> validcount == validcount ) continue ; line -> validcount = validcount ; v1 = line -> v1 ; v2 = line -> v2 ; s1 = P_DivlineSide ( v1 -> x , v1 -> y , strace ) ; s2 = P_DivlineSide ( v2 -> x , v2 -> y , strace ) ; if ( s1 == s2 ) continue ; divl . x = v1 -> x ; divl . y = v1 -> y ; divl . dx = v2 -> x - v1 -> x ; divl . dy = v2 -> y - v1 -> y ; s1 = P_DivlineSide ( strace -> x , strace -> y , & divl ) ; s2 = P_DivlineSide ( t2x , t2y , & divl ) ; if ( s1 == s2 ) continue ; if ( ! ( line -> flags & ML_TWOSIDED ) ) return false ; side = seg -> side ; front = & sectors [ sides [ line -> sidenum [ side ] ] . sector ] ; back = ( line -> flags & ML_TWOSIDED ) ? & sectors [ sides [ line -> sidenum [ side ^ 1 ] ] . sector ] : 0 ; if ( front -> floorheight == back -> floorheight && front -> ceilingheight == back -> ceilingheight ) continue ; if ( front -> ceilingheight < back -> ceilingheight ) opentop = front -> ceilingheight ; else opentop = back -> ceilingheight ; if ( front -> floorheight > back -> floorheight ) openbottom = front -> floorheight ; else openbottom = back -> floorheight ; if ( openbottom >= opentop ) return false ; frac = P_InterceptVector2 ( strace , & divl ) ; if ( front -> floorheight != back -> floorheight ) { slope = FixedDiv ( openbottom - sightzstart , frac ) ; if ( slope > sw -> bottomslope ) sw -> bottomslope = slope ; } if ( front -> ceilingheight != back -> ceilingheight ) { slope = FixedDiv ( opentop - sightzstart , frac ) ; if ( slope < sw -> topslope ) sw -> topslope = slope ; } if ( sw -> topslope <= sw -> bottomslope ) return false ; } return true ; }
PS_CrossSubsector
Returns true if strace crosses the given subsector successfuly
PS_CrossSubsector Returns true if strace crosses the given subsector successfuly
// check lines // allready checked other side? // line isn't crossed? // line isn't crossed? // stop because it is not two sided anyway // might do this after updating validcount? // crosses a two sided line // no wall to block sight with? // possible occluder // because of ceiling height differences // because of ceiling height differences // quick test for totally closed doors // stop // stop // passed the subsector ok