bool FloorFace::intersectRay(const Math::Ray &ray, Math::Vector3d &intersection) const { // Compute the triangle plane normal Math::Vector3d n = Math::Vector3d::crossProduct(_vertices[1] - _vertices[0], _vertices[2] - _vertices[0]); if (n == Math::Vector3d()) { return false; // We don't handle degenerate triangles } // Point on triangle plane: dot(P - _vertices[0], n) = 0 // Point on ray: P = origin + r * direction // Point on both => r = - dot(n, origin - _vertices[0]) / dot(n, direction) float num = -Math::Vector3d::dotProduct(n, ray.origin() - _vertices[0]); float denom = Math::Vector3d::dotProduct(n, ray.direction()); if (fabs(denom) < 0.00001) { // The ray is parallel to the plane return false; } float r = num / denom; if (r < 0.0) { // The ray goes away from the triangle return false; } // Compute the intersection point between the triangle plane and the ray intersection = ray.origin() + r * ray.direction(); // Check the intersection point is inside the triangle return isPointInside(intersection); }
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)); }
bool BoneNode::intersectRay(const Math::Ray &ray) const { Math::Ray localRay = ray; localRay.translate(-_animPos); localRay.rotate(_animRot.inverse()); return localRay.intersectAABB(_boundingBox); }
bool VisualActor::intersectRay(const Math::Ray &ray, const Math::Vector3d position, float direction) { Math::Matrix4 inverseModelMatrix = getModelMatrix(position, direction); inverseModelMatrix.inverse(); // Build an object local ray from the world ray Math::Ray localRay = ray; localRay.transform(inverseModelMatrix); return _model->intersectRay(localRay); }
bool BoundingEllipsoid::intersects (math::Ray &r, bool segment, CollisionResultSet::Info& info) { math::Matrix4f transform = scale * rotation * translation; math::Matrix4f invTransform = transform.inverse(); math::Vec3f orig = invTransform * r.getOrig(); math::Vec3f ext = invTransform * r.getExt(); math::Ray tRay (orig, ext); math::Vec3f mtu; BoundingSphere bs(math::Vec3f(0, 0, 0), 1); if (!bs.intersects(tRay, segment, info)) return false; return false; }
bool BoundingEllipsoid::intersectsWhere(math::Ray& r, math::Vec3f& near, math::Vec3f& far, CollisionResultSet::Info& info) { math::Matrix4f transform = scale * rotation * translation; math::Matrix4f invTransform = transform.inverse(); math::Vec3f orig = invTransform * r.getOrig(); math::Vec3f ext = invTransform * r.getExt(); math::Ray tRay (orig, ext); math::Vec3f i1, i2; BoundingSphere bs(math::Vec3f(0, 0, 0), 1); if (!bs.intersectsWhere(tRay, i1, i2, info)) return false; near = transform * i1; far = transform * i2; return true; }
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ //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); }
void BVHSceneTree::findIntersections(BVHSceneNode* node, Math::Ray const& ray, std::vector<std::pair<SceneObject*, float>>& objects) const { if(node) { Math::Vector3f point; float distance; if(ray.intersects(node->bounds, point, distance)) { if((node->type == SceneNodeType::Leaf) && (node->object)) { objects.emplace_back(std::make_pair(node->object, distance)); } else { findIntersections(node->left, ray, objects); findIntersections(node->right, ray, objects); } } } }
bool Planet::get_color(ColorRGBA& resulting_color, const Vector2& screen, Math::Ray ray, gfloat& distance)const { if(sphere.radius<=0.f) return false; ray.transform(sphere.inv_transformation); if(!sphere.intersects_local(ray, distance)) return false; Vector3 p = ray.origin + ray.dir*distance; p.normalize(); p *= sphere.radius; Vector3 normal = p; normal *= 1.f/sphere.radius; if(Manager::get_settings().get_dbg_normal()) { resulting_color.set_direction(normal); }else { Vector2 uv; vec_to_uv(uv, normal); if(Manager::get_settings().get_dbg_uv()) { resulting_color.set(uv.x, uv.y, 0.f, 1.f); }else { shader(resulting_color, screen, uv, normal, ray); } } return true; }
float FloorFace::distanceToRay(const Math::Ray &ray) const { Math::Vector3d center = getCenter(); return Math::Vector3d::crossProduct(ray.direction(), center - ray.origin()).getMagnitude(); }