diff options
author | Robert Vollmert <rvollmert@gmx.net> | 2009-10-31 09:08:37 +0100 |
---|---|---|
committer | Robert Vollmert <rvollmert@gmx.net> | 2009-11-01 21:45:24 +0100 |
commit | 2130c831446f0b7f2487a4704503901bf1e375e7 (patch) | |
tree | a7b601a88b936ccf45d579cd0e8d43caad6d9b14 /crawl-ref/source | |
parent | a062c664e4802851fba4cc5a001e49a61698f4a3 (diff) | |
download | crawl-ref-2130c831446f0b7f2487a4704503901bf1e375e7.tar.gz crawl-ref-2130c831446f0b7f2487a4704503901bf1e375e7.zip |
Change corner handling.
ray_def should now deal with hitting corners gracefully, though the
raycasting will still discard such rays. If a ray hits a corner
between two diamonds, it will stay there, and calling ray_def::pos
will arbitrarily give one of the squares -- this is not optimal,
but these rays shouldn't usually show up anyway.
Diffstat (limited to 'crawl-ref/source')
-rw-r--r-- | crawl-ref/source/geom2d.cc | 23 | ||||
-rw-r--r-- | crawl-ref/source/geom2d.h | 3 | ||||
-rw-r--r-- | crawl-ref/source/ray.cc | 32 | ||||
-rw-r--r-- | crawl-ref/source/ray.h | 3 |
4 files changed, 54 insertions, 7 deletions
diff --git a/crawl-ref/source/geom2d.cc b/crawl-ref/source/geom2d.cc index 62930aec9c..eef902f14d 100644 --- a/crawl-ref/source/geom2d.cc +++ b/crawl-ref/source/geom2d.cc @@ -68,8 +68,9 @@ static double tdist(const ray &r, const lineseq &ls) } // Shoot the ray inside the next cell. -// Returns true if succesfully advanced, false if aborted due to corner. -bool nextcell(ray &r, const grid &g, bool pass_corner) +// Returns true if succesfully advanced into a new cell, +// false if it hit a corner. +bool nextcell(ray &r, const grid &g) { // ASSERT(!parallel(g.vert, g.horiz)); lineseq ls; @@ -84,7 +85,12 @@ bool nextcell(ray &r, const grid &g, bool pass_corner) double sd = tdist(r, g.ls1); double td = tdist(r, g.ls2); if (double_is_zero(s - t)) + { + // Move onto the corner. The fact that we're on a corner + // should be tracked externally. + r.advance(s); return (false); + } double dmin = std::min(s,t); double dnext = std::min(std::max(s,t), dmin + std::min(sd, td)); r.advance((dmin + dnext) / 2.0); @@ -96,6 +102,19 @@ bool nextcell(ray &r, const grid &g, bool pass_corner) return (true); } +void movehalfcell(ray &r, const grid &g) +{ + // ASSERT(!parallel(g.vert, g.horiz)); + lineseq ls; + double t; + if (parallel(r.dir, g.ls1.f)) + t = tdist(r, g.ls2); + else if (parallel(r.dir, g.ls2.f)) + t = tdist(r, g.ls1); + else + t = std::min(tdist(r, g.ls1), tdist(r, g.ls2)); + r.advance(0.5 * t); +} // vector space implementation diff --git a/crawl-ref/source/geom2d.h b/crawl-ref/source/geom2d.h index d65ea06842..37b62745df 100644 --- a/crawl-ref/source/geom2d.h +++ b/crawl-ref/source/geom2d.h @@ -76,7 +76,8 @@ struct grid double intersect(const ray &r, const line &l); double nextintersect(const ray &r, const lineseq &ls); -bool nextcell(ray &r, const grid &g, bool pass_corner); +bool nextcell(ray &r, const grid &g); +void movehalfcell(ray &r, const grid &g); } diff --git a/crawl-ref/source/ray.cc b/crawl-ref/source/ray.cc index e6952f2102..bbf812009f 100644 --- a/crawl-ref/source/ray.cc +++ b/crawl-ref/source/ray.cc @@ -20,16 +20,42 @@ static int ifloor(double d) coord_def ray_def::pos() const { - // TODO: Assert we're in a central diamond. + // XXX: pretty arbitrary if we're just on a corner. int x = ifloor(r.start.x); int y = ifloor(r.start.y); return (coord_def(x, y)); } +// Return false if we passed or hit a corner. bool ray_def::advance() { - return (geom::nextcell(r, diamonds, true) - && geom::nextcell(r, diamonds, false)); + if (on_corner) + { + on_corner = false; + geom::movehalfcell(r, diamonds); + } + else + { + // Starting inside a diamond. + bool c = !geom::nextcell(r, diamonds); + + if (c) + { + // r is now on a corner, going from diamond to diamond. + geom::movehalfcell(r, diamonds); + return (false); + } + } + // Now inside a non-diamond. + + if (geom::nextcell(r, diamonds)) + return (true); + else + { + // r is now on a corner, going from non-diamond to non-diamond. + on_corner = true; + return (false); + } } void ray_def::advance_and_bounce() diff --git a/crawl-ref/source/ray.h b/crawl-ref/source/ray.h index 477f8fcbf7..671ca0fa8a 100644 --- a/crawl-ref/source/ray.h +++ b/crawl-ref/source/ray.h @@ -11,11 +11,12 @@ struct ray_def { geom::ray r; + bool on_corner; int cycle_idx; ray_def() {} ray_def(const geom::ray& _r) - : r(_r), cycle_idx(0) {} + : r(_r), on_corner(false), cycle_idx(0) {} coord_def pos() const; bool advance(); |