bool intersect(CRay& _ray, float* _thit, CLocalGeo* _local, int& _id) { if (_ray.m_id == m_id) return false; V3f E1 = m_V0 - m_V1; V3f E2 = m_V0 - m_V2; V3f S = m_V0 - _ray.m_pos; float d = det(_ray.m_dir, E1, E2); if (d < EPS && d > -EPS) return false; float d1 = det(S, E1, E2); float t = d1 / d; if (t < _ray.m_t_min || t > _ray.m_t_max) return false; float d2 = det(_ray.m_dir, S, E2); float beta = d2 / d; if (beta < -EPS || beta - 1 > EPS) return false; float d3 = det(_ray.m_dir, E1, S); float gamma = d3 / d; if (gamma < -EPS || gamma - 1 > EPS || beta + gamma - 1 > EPS) return false; *_thit = t; _id = m_id; _local->m_pos = _ray.Ray_t(t); _local->m_n = (m_V0-m_V1).cross(m_V0-m_V2); _local->m_n = _local->m_n / _local->m_n.norm(); return true; }
bool intersect(CRay& _ray, float* _thit, CLocalGeo* _local, int& _id) { if (_ray.m_id == m_id) return false; float t; V3f oc = _ray.m_pos - m_c; float a = _ray.m_dir.dot(_ray.m_dir); // dir should be unit float b = _ray.m_dir.dot(oc); float c = oc.dot(oc) - m_r2; float delta = b * b - a * c; if (delta < 0) // no solution return false; else if (delta > -EPS && delta < EPS) { // one solution t = - b / a; if (t > _ray.m_t_max || t < _ray.m_t_min) // out of range return false; } else { // two solutions float deltasqrt = sqrt(delta); float t1 = (- b - deltasqrt) / a; float t2 = (- b + deltasqrt) / a; bool flag = false; t = _ray.m_t_max; if (t1 <= _ray.m_t_max && t1 >= _ray.m_t_min) { flag = true; t = min(t, t1); } if (t2 <= _ray.m_t_max && t2 >= _ray.m_t_min) { flag = true; t = min(t, t2); } if (!flag) // both out of range return false; } // pass t, compute CLocalGeo *_thit = t; _id = m_id; _local->m_pos = _ray.Ray_t(t); _local->m_n = _local->m_pos - m_c; _local->m_n = _local->m_n / _local->m_n.norm(); return true; }