bool vec3_t::RayCylinderIntersect(const vec3_t& pStart, const vec3_t& pDir, const vec3_t& edgeStart, const vec3_t& edgeEnd, const float radius, float* f) { // math. for 3d game programming 2nd ed. page 270 // assert(edgeStart != edgeEnd); // sloppy level design const vec3_t pa = edgeEnd - edgeStart; const vec3_t s0 = pStart - edgeStart; const float pa_squared = pa.AbsSquared(); const float pa_isquared = 1.0f/pa_squared; // a const float pva = pDir * pa; const float a = pDir.AbsSquared() - pva*pva*pa_isquared; // b const float b = s0*pDir - (s0*pa)*(pva)*pa_isquared; // c const float ps0a = s0*pa; const float c = s0.AbsSquared() - radius*radius - ps0a*ps0a*pa_isquared; const float dis = b*b - a*c; if(dis < 0) return false; *f = (-b - lynxmath::Sqrt(dis))/a; const float collision = (pStart + *f*pDir - edgeStart)*pa; return collision >= 0 && collision <= pa_squared; }