bool static rayIntersectsRect(const Math::Ray &ray, const Math::Vector3d &topLeft, const Math::Vector3d &topRight, const Math::Vector3d &bottomLeft, const Math::Vector3d &bottomRight) { // Orthogonal basis in rectangle coordinates Math::Vector3d topRectDir = topRight - topLeft; Math::Vector3d leftRectDir = bottomLeft - topLeft; Math::Vector3d n = Math::Vector3d::crossProduct(topRectDir, leftRectDir); float nDotDir = Math::Vector3d::dotProduct(n, ray.getDirection()); if (ABS(nDotDir) < 1e-6) { // The ray is coplanar with the rectangle return false; } // Solution to the system (intersection of line with plane): // Line equation: V = ray.origin + t * ray.direction // Plane equation: dot(n, V) = 0 float t = -Math::Vector3d::dotProduct(n, ray.getOrigin() - topLeft) / nDotDir; if (t < 0.0) { // The intersection is not in the ray direction return false; } // Intersection point in world coordinates Math::Vector3d intersection = ray.getOrigin() + ray.getDirection() * t; // Intersection point in 2D rect coordinates Math::Vector3d intersect2D = intersection - topLeft; float u = Math::Vector3d::dotProduct(intersect2D, topRectDir); float v = Math::Vector3d::dotProduct(intersect2D, leftRectDir); // Intersection inside the rectangle return (u >= 0.0 && u <= Math::Vector3d::dotProduct(topRectDir, topRectDir) && v >= 0.0 && v <= Math::Vector3d::dotProduct(leftRectDir, leftRectDir)); }
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ //see http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?f=9&t=4152&hilit=raytest //for reference void PhysicsZone::rayCast(Math::Ray _ray, Math::Real _maxDistance, I_CollisionVisitor& _visitor) { Math::Vector3 offset = _ray.getDirection(); offset.normalize(); offset *= _maxDistance; Math::Point3 endpoint = _ray.getOrigin() + offset; //(m_pZone, _ray.getOrigin().m_array, endpoint.m_array, rayCastFilter, &rayCastQuery, rayCastPrefilter); btVector3 tquatFrom = btVector3(_ray.getOrigin().m_x,_ray.getOrigin().m_y,_ray.getOrigin().m_z); btVector3 tquatTo = btVector3(_ray.getOrigin().m_x,_ray.getOrigin().m_y,_ray.getOrigin().m_z); RayResultCallback resultCallback(tquatFrom,tquatTo); m_pZone->rayTest(tquatFrom,tquatTo,resultCallback); }