Implementation derived from Wild Magic (Version 2) Software Library, available from http://www.geometrictools.com/Downloads/WildMagic2p5.zip under free license
| 291 | /// Implementation derived from Wild Magic (Version 2) Software Library, available |
| 292 | /// from http://www.geometrictools.com/Downloads/WildMagic2p5.zip under free license |
| 293 | bool SpherePrimitiveEvaluator::intersectionPoint( const Imath::V3f &origin, const Imath::V3f &direction, |
| 294 | PrimitiveEvaluator::Result *result, float maxDistance ) const |
| 295 | { |
| 296 | assert( dynamic_cast<Result *>( result ) ); |
| 297 | |
| 298 | Result *sr = static_cast<Result *>( result ); |
| 299 | |
| 300 | Imath::V3f dir = direction.normalized(); |
| 301 | (void)direction; |
| 302 | float a0 = origin.dot( origin ) - m_sphere->radius() * m_sphere->radius(); |
| 303 | float a1 = dir.dot( origin ); |
| 304 | float discr = a1 * a1 - a0; |
| 305 | |
| 306 | if (discr < 0.0) |
| 307 | { |
| 308 | return false; |
| 309 | } |
| 310 | |
| 311 | if ( discr >= std::numeric_limits<float>::epsilon() ) |
| 312 | { |
| 313 | float root = sqrt( discr ); |
| 314 | float t0 = -a1 - root; |
| 315 | float t1 = -a1 + root; |
| 316 | |
| 317 | Imath::V3f p0 = origin + t0 * dir; |
| 318 | Imath::V3f p1 = origin + t1 * dir; |
| 319 | |
| 320 | if ( t0 >= 0.0 ) |
| 321 | { |
| 322 | if ( t1 >= 0.0 ) |
| 323 | { |
| 324 | if ( (origin - p0).length2() < ( origin - p1 ).length2() ) |
| 325 | { |
| 326 | sr->m_p = p0; |
| 327 | } |
| 328 | else |
| 329 | { |
| 330 | sr->m_p = p1; |
| 331 | } |
| 332 | } |
| 333 | else |
| 334 | { |
| 335 | sr->m_p = p0; |
| 336 | } |
| 337 | } |
| 338 | else if ( t1 >= 0.0 ) |
| 339 | { |
| 340 | sr->m_p = p1; |
| 341 | } |
| 342 | else |
| 343 | { |
| 344 | return false; |
| 345 | } |
| 346 | } |
| 347 | else |
| 348 | { |
| 349 | float t = -a1; |
| 350 |