From a5b20dcd57ddf7bdac8d9bce1aabf934badd837d Mon Sep 17 00:00:00 2001 From: Paweł Redman Date: Thu, 12 Apr 2018 14:00:53 +0200 Subject: Ray tracing against cmodels (WIP). --- src/world.cpp | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 70 insertions(+), 6 deletions(-) (limited to 'src/world.cpp') 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_; -- cgit