summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source
diff options
context:
space:
mode:
authorRobert Vollmert <rvollmert@gmx.net>2009-10-31 09:08:37 +0100
committerRobert Vollmert <rvollmert@gmx.net>2009-11-01 21:45:24 +0100
commit2130c831446f0b7f2487a4704503901bf1e375e7 (patch)
treea7b601a88b936ccf45d579cd0e8d43caad6d9b14 /crawl-ref/source
parenta062c664e4802851fba4cc5a001e49a61698f4a3 (diff)
downloadcrawl-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.cc23
-rw-r--r--crawl-ref/source/geom2d.h3
-rw-r--r--crawl-ref/source/ray.cc32
-rw-r--r--crawl-ref/source/ray.h3
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();