summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source
diff options
context:
space:
mode:
Diffstat (limited to 'crawl-ref/source')
-rw-r--r--crawl-ref/source/geom2d.cc8
-rw-r--r--crawl-ref/source/geom2d.h2
-rw-r--r--crawl-ref/source/ray.cc44
-rw-r--r--crawl-ref/source/ray.h4
4 files changed, 55 insertions, 3 deletions
diff --git a/crawl-ref/source/geom2d.cc b/crawl-ref/source/geom2d.cc
index de8d86724b..35ec5138ae 100644
--- a/crawl-ref/source/geom2d.cc
+++ b/crawl-ref/source/geom2d.cc
@@ -44,6 +44,11 @@ double intersect(const ray &r, const line &l)
return (t);
}
+double lineseq::index(const vector &v) const
+{
+ return ((f(v) - offset) / dist);
+}
+
// Find the next intersection of r with a line in ls.
double nextintersect(const ray &r, const lineseq &ls)
{
@@ -129,6 +134,9 @@ vector reflect(const vector &v, const form &f)
return (v - 2 * f(v)/f(n) * n);
}
+
+
+//////////////////////////////////////////////////
// vector space implementation
const vector& vector::operator+=(const vector &v)
diff --git a/crawl-ref/source/geom2d.h b/crawl-ref/source/geom2d.h
index 504f1ed77a..6f7e147ab1 100644
--- a/crawl-ref/source/geom2d.h
+++ b/crawl-ref/source/geom2d.h
@@ -70,6 +70,8 @@ struct lineseq
lineseq() {}
lineseq(double a, double b, double o, double d)
: f(a,b), offset(o), dist(d) {}
+
+ double index(const vector &v) const;
};
struct grid
diff --git a/crawl-ref/source/ray.cc b/crawl-ref/source/ray.cc
index dff1d3e82a..56fc3058d1 100644
--- a/crawl-ref/source/ray.cc
+++ b/crawl-ref/source/ray.cc
@@ -15,6 +15,7 @@
#include <cmath>
+#include "los.h"
#include "ray.h"
#include "geom2d.h"
@@ -26,6 +27,36 @@ static int ifloor(double d)
return static_cast<int>(floor(d));
}
+static bool double_is_integral(double d)
+{
+ return (double_is_zero(d - round(d)));
+}
+
+
+// Is v in a diamond?
+static bool in_diamond(const geom::vector &v)
+{
+ int i1 = ifloor(diamonds.ls1.index(v));
+ int i2 = ifloor(diamonds.ls2.index(v));
+ return ((i1 + i2) % 2 == 0);
+}
+
+// Is v in the interiour of a diamond?
+static bool in_diamond_int(const geom::vector &v)
+{
+ double d1 = diamonds.ls1.index(v);
+ double d2 = diamonds.ls2.index(v);
+ return (!double_is_integral(d1) && !double_is_integral(d2));
+}
+
+// Is v an intersection of grid lines?
+static bool is_corner(const geom::vector &v)
+{
+ double d1 = diamonds.ls1.index(v);
+ double d2 = diamonds.ls2.index(v);
+ return (double_is_integral(d1) && double_is_integral(d2));
+}
+
coord_def ray_def::pos() const
{
// XXX: pretty arbitrary if we're just on a corner.
@@ -37,8 +68,10 @@ coord_def ray_def::pos() const
// Return false if we passed or hit a corner.
bool ray_def::advance()
{
+ ASSERT(on_corner || in_diamond_int(r.start));
if (on_corner)
{
+ ASSERT (is_corner(r.start));
on_corner = false;
r.move_half_cell(diamonds);
}
@@ -54,13 +87,19 @@ bool ray_def::advance()
return (false);
}
}
+
// Now inside a non-diamond.
+ ASSERT(!in_diamond(r.start));
if (r.to_next_cell(diamonds))
+ {
+ ASSERT(in_diamond_int(r.start));
return (true);
+ }
else
{
// r is now on a corner, going from non-diamond to non-diamond.
+ ASSERT(is_corner(r.start));
on_corner = true;
return (false);
}
@@ -68,7 +107,10 @@ bool ray_def::advance()
void ray_def::bounce(const reflect_grid &rg)
{
- // XXX
+ ASSERT(in_diamond(r.start));
+ // Find out which side of the diamond r leaves through.
+ geom::ray copy = r;
+
r.dir = -r.dir;
}
diff --git a/crawl-ref/source/ray.h b/crawl-ref/source/ray.h
index cc7688571d..6748090348 100644
--- a/crawl-ref/source/ray.h
+++ b/crawl-ref/source/ray.h
@@ -17,9 +17,9 @@ struct ray_def
bool on_corner;
int cycle_idx;
- ray_def() {}
+ ray_def() : on_corner(false), cycle_idx(-1) {}
ray_def(const geom::ray& _r)
- : r(_r), on_corner(false), cycle_idx(0) {}
+ : r(_r), on_corner(false), cycle_idx(-1) {}
coord_def pos() const;
bool advance();