/* * ============== * = * = P_MakeDivline * = * ============== */ public static void P_MakeDivline(r_local.line_t li, p_local.divline_t dl) { dl.x = li.v1.x; dl.y = li.v1.y; dl.dx = li.dx; dl.dy = li.dy; }
/* * ================== * = * = P_SightBlockLinesIterator * = * =================== */ public static bool P_SightBlockLinesIterator(int x, int y) { int offset; short list; r_local.line_t ld; int s1, s2; p_local.divline_t dl = new p_local.divline_t(); offset = y * p_setup.bmapwidth + x; offset = p_setup.blockmaplump[p_setup.blockmap + offset]; for (int i = offset; ; i++) { list = p_setup.blockmaplump[i]; if (list == -1) { break; } ld = p_setup.lines[list]; if (ld.validcount == r_main.validcount) { continue; // line has already been checked } ld.validcount = r_main.validcount; s1 = p_maputl.P_PointOnDivlineSide(ld.v1.x, ld.v1.y, p_maputl.trace); s2 = p_maputl.P_PointOnDivlineSide(ld.v2.x, ld.v2.y, p_maputl.trace); if (s1 == s2) { continue; // line isn't crossed } p_maputl.P_MakeDivline(ld, dl); s1 = p_maputl.P_PointOnDivlineSide(p_maputl.trace.x, p_maputl.trace.y, dl); s2 = p_maputl.P_PointOnDivlineSide(p_maputl.trace.x + p_maputl.trace.dx, p_maputl.trace.y + p_maputl.trace.dy, dl); if (s1 == s2) { continue; // line isn't crossed } // try to early out the check if (ld.backsector == null) { return(false); // stop checking } // store the line for later intersection testing p_maputl.intercepts[p_maputl.intercept_p].line = ld; p_maputl.intercept_p++; } return(true); // everything was checked }
public override bool func(DoomDef.mobj_t thing) { int x1, y1, x2, y2; int s1, s2; bool tracepositive; p_local.divline_t dl = new p_local.divline_t(); int frac; tracepositive = (trace.dx ^ trace.dy) > 0; // check a corner to corner crossection for hit if (tracepositive) { x1 = thing.x - thing.radius; y1 = thing.y + thing.radius; x2 = thing.x + thing.radius; y2 = thing.y - thing.radius; } else { x1 = thing.x - thing.radius; y1 = thing.y - thing.radius; x2 = thing.x + thing.radius; y2 = thing.y + thing.radius; } s1 = p_maputl.P_PointOnDivlineSide(x1, y1, trace); s2 = p_maputl.P_PointOnDivlineSide(x2, y2, trace); if (s1 == s2) { return(true); // line isn't crossed } dl.x = x1; dl.y = y1; dl.dx = x2 - x1; dl.dy = y2 - y1; frac = P_InterceptVector(trace, dl); if (frac < 0) { return(true); // behind source } intercepts[intercept_p].frac = frac; intercepts[intercept_p].isaline = false; intercepts[intercept_p].thing = thing; intercept_p++; return(true); // keep going }
/* * ==================== * = * = P_SightTraverseIntercepts * = * = Returns true if the traverser function returns true for all lines * ==================== */ public static bool P_SightTraverseIntercepts() { int count; int dist; p_local.intercept_t scan, in_; p_local.divline_t dl = new p_local.divline_t(); count = p_maputl.intercept_p; // // calculate intercept distance // for (int i = 0; i < p_maputl.intercept_p; ++i) { scan = p_maputl.intercepts[i]; p_maputl.P_MakeDivline(scan.line, dl); scan.frac = p_maputl.P_InterceptVector(p_maputl.trace, dl); } // // go through in order // in_ = null; // shut up compiler warning while ((count--) != 0) { dist = DoomDef.MAXINT; for (int i = 0; i < p_maputl.intercept_p; ++i) { scan = p_maputl.intercepts[i]; if (scan.frac < dist) { dist = scan.frac; in_ = scan; } } if (in_ == null) { continue; } if (!PTR_SightTraverse(in_)) { return(false); // don't bother going farther } in_.frac = DoomDef.MAXINT; } return(true); // everything was traversed }
/* * =============== * = * = P_InterceptVector * = * = Returns the fractional intercept point along the first divline * = * = This is only called by the addthings and addlines traversers * =============== */ public static int P_InterceptVector(p_local.divline_t v2, p_local.divline_t v1) { int frac, num, den; den = DoomDef.FixedMul(v1.dy >> 8, v2.dx) - DoomDef.FixedMul(v1.dx >> 8, v2.dy); if (den == 0) { return(0); } num = DoomDef.FixedMul((v1.x - v2.x) >> 8, v1.dy) + DoomDef.FixedMul((v2.y - v1.y) >> 8, v1.dx); frac = d_main.FixedDiv(num, den); return(frac); }
public override bool func(r_local.line_t ld) { int s1, s2; int frac; p_local.divline_t dl = new p_local.divline_t(); // avoid precision problems with two routines if (trace.dx > DoomDef.FRACUNIT * 16 || trace.dy > DoomDef.FRACUNIT * 16 || trace.dx < -DoomDef.FRACUNIT * 16 || trace.dy < -DoomDef.FRACUNIT * 16) { s1 = p_maputl.P_PointOnDivlineSide(ld.v1.x, ld.v1.y, trace); s2 = p_maputl.P_PointOnDivlineSide(ld.v2.x, ld.v2.y, trace); } else { s1 = P_PointOnLineSide(trace.x, trace.y, ld); s2 = P_PointOnLineSide(trace.x + trace.dx, trace.y + trace.dy, ld); } if (s1 == s2) { return(true); // line isn't crossed } // // hit the line // p_maputl.P_MakeDivline(ld, dl); frac = p_maputl.P_InterceptVector(trace, dl); if (frac < 0) { return(true); // behind source } // try to early out the check if (earlyout && frac < DoomDef.FRACUNIT && ld.backsector == null) { return(false); // stop checking } intercepts[intercept_p].frac = frac; intercepts[intercept_p].isaline = true; intercepts[intercept_p].line = ld; intercept_p++; return(true); // continue }
/* * ================== * = * = P_PointOnDivlineSide * = * = Returns 0 or 1 * ================== */ public static int P_PointOnDivlineSide(int x, int y, p_local.divline_t line) { int dx, dy; int left, right; if (line.dx == 0) { if (x <= line.x) { return((line.dy > 0) ? 1 : 0); } return((line.dy < 0) ? 1 : 0); } if (line.dy == 0) { if (y <= line.y) { return((line.dx < 0) ? 1 : 0); } return((line.dx > 0) ? 1 : 0); } dx = (x - line.x); dy = (y - line.y); // try to quickly decide by looking at sign bits if (((line.dy ^ line.dx ^ dx ^ dy) & 0x80000000) != 0) { if (((line.dy ^ dx) & 0x80000000) != 0) { return(1); // (left is negative) } return(0); } left = DoomDef.FixedMul(line.dy >> 8, dx >> 8); right = DoomDef.FixedMul(dy >> 8, line.dx >> 8); if (right < left) { return(0); // front side } return(1); // back side }