summaryrefslogtreecommitdiff
path: root/src/world.cpp
diff options
context:
space:
mode:
authorPaweł Redman <pawel.redman@gmail.com>2018-04-12 14:00:53 +0200
committerPaweł Redman <pawel.redman@gmail.com>2018-04-12 14:00:53 +0200
commita5b20dcd57ddf7bdac8d9bce1aabf934badd837d (patch)
treee05853e98e2481f5ac939919b58227190e1a07d0 /src/world.cpp
parent30c5c419aedd0e5aae92be6e0eee83f0b6690c6e (diff)
Ray tracing against cmodels (WIP).
Diffstat (limited to 'src/world.cpp')
-rw-r--r--src/world.cpp76
1 files changed, 70 insertions, 6 deletions
diff --git a/src/world.cpp b/src/world.cpp
index 640ac6e..b03105e 100644
--- a/src/world.cpp
+++ b/src/world.cpp
@@ -319,6 +319,76 @@ static inline size_t quadrant(v2f_t dx)
}
}
+trace_t ray_v_rect(v2f_t start, v2f_t end, rectf_t rect)
+{
+ v2f_t dx, tdelta, dims;
+ size_t quad;
+ trace_t res;
+
+ if (rect.contains(start)) {
+ res.hit = true;
+ res.end = start;
+ res.frac = 0.0f;
+ return res;
+ }
+
+ dx = end - start;
+
+ quad = quadrant(dx);
+ if (quad == 4)
+ goto out_no_hit;
+
+ // If necessary, transform (with simple X/Y reflections) the coordinate
+ // system, so that dx lies in the first quadrant.
+
+ start ^= transforms[quad];
+ dx ^= transforms[quad];
+ end ^= transforms[quad];
+
+ dims = rect.dims();
+ rect.v[0] ^= transforms[quad];
+ rect.v[1] ^= transforms[quad];
+
+ // Find the closest point on the rectangle and transform the coordinates
+ // so that it lies at (0, 0).
+
+ tdelta[0] = std::min(rect.v[0][0], rect.v[1][0]);
+ tdelta[1] = std::min(rect.v[0][1], rect.v[1][1]);
+ start -= tdelta;
+
+ // Project onto x = 0.
+ res.frac = -start[0] / dx[0];
+ if (res.frac >= 0.0f && res.frac <= 1.0f) {
+ float y;
+
+ y = start[1] + res.frac * dx[1];
+ if (y >= 0 && y <= dims[1]) {
+ res.hit = true;
+ res.end = (v2f_t(0, y) + tdelta) ^ transforms[quad];
+ return res;
+ }
+ }
+
+ // Project onto y = 0.
+ res.frac = -start[1] / dx[1];
+ if (res.frac >= 0.0f && res.frac <= 1.0f) {
+ float x;
+
+ x = start[0] + res.frac * dx[0];
+ if (x >= 0 && x <= dims[0]) {
+ res.hit = true;
+ res.end = (v2f_t(x, 0) + tdelta) ^ transforms[quad];
+ return res;
+ }
+ }
+
+out_no_hit:
+ res.hit = false;
+ res.end = end ^ transforms[quad];
+ res.frac = 1.0f;
+ return res;
+}
+
trace_t world_t::trace(v2f_t start, v2f_t end, cflags_t cflags)
{
v2f_t x, dx;
@@ -382,12 +452,6 @@ trace_t world_t::trace(v2f_t start, v2f_t end, cflags_t cflags)
}
}
-trace_t trace_cmodel(v2f_t start, v2f_t end, const cmodel_t *cmodel)
-{
- // TODO
- return {0};
-}
-
entity_t::entity_t(int type_)
{
type = type_;