bool SceneNode::hit(const Ray& ray, double &tmin, Shading &s) { // transform ray so in object co-ordinates Ray local_ray(ray); local_ray.direction = m_invtrans * ray.direction; local_ray.origin = m_invtrans * ray.origin; Shading shading(s.world); double t; tmin = 10E24; Vector3D normal; Material *mat; for (ChildList::const_iterator it = m_children.begin(); it != m_children.end(); it++) { SceneNode *object = (*it); if (object->hit(local_ray, t, shading) && (t < tmin)) { tmin = t; normal = shading.hit_normal; mat = shading.material; } } if (shading.hit_object) { s.hit_object = true; s.t = tmin; s.hit_normal = m_invtrans.transpose() * normal; s.material = mat; return true; } return false; }
bool Mesh::hit(const Ray& ray, double &tmin, Shading &s) const { Ray local_ray(ray); Shading shading(s.world); double t; tmin = 10E24; Vector3D normal; // check bounding box first Shading shading2(s.world); bool was_bound = m_boundbox->hit(ray,tmin,shading2); if (!m_boundbox->hit(ray,tmin,shading2)) { return false; } tmin = 10E24; for (unsigned int i=0; i<m_triangles.size(); i++) { Triangle triangle = m_triangles[i]; if (triangle.hit(local_ray, t, shading) && (t < tmin)) { shading.hit_object = true; tmin = t; normal = shading.hit_normal; } } if (shading.hit_object) { s.hit_object = true; s.t = tmin; s.hit_normal = normal; return true; } return false; }
bool GeometryNode::hit(const Ray& ray, double &tmin, Shading &s) { // transform ray so in object co-ordinates Ray local_ray(ray); local_ray.direction = m_invtrans * ray.direction; local_ray.origin = m_invtrans * ray.origin; // only hit if primitive hit if (m_primitive->hit(local_ray, tmin, s)) { s.hit_object = true; s.material = m_material; // translate normal back to WCS s.hit_normal = m_invtrans.transpose() * s.hit_normal; return true; } return false; }
bool Rectangle::Intersect(const Ray &ray, const RayInterval &interval, SurfaceInteraction *const interaction) const { // Compute local ray Ray local_ray = TransformRay(world_to_local, ray); // Check intersection with plane if (std::abs(local_ray.Direction().y()) > 10e-6f) { // Compute intersection with plane float t = -local_ray.Origin().y() * local_ray.InvDirection().y(); // Check boundaries if (interval.Inside(t)) { // Compute intersection point Vector3f hit_p = local_ray(t); // Check hit point inside rectangle if (hit_p.x() > -x_size / 2.f && hit_p.x() < x_size / 2.f && hit_p.z() > -z_size / 2.f && hit_p.z() < z_size / 2.f) { // Fill interaction interaction->hit_point = hit_p; interaction->geom_frame = Frame(Vector3f(1.f, 0.f, 0.f), Vector3f(0.f, 1.f, 0.f), Vector3f(0.f, 0.f, 1.f)); interaction->sh_frame = Frame(Vector3f(1.f, 0.f, 0.f), Vector3f(0.f, 1.f, 0.f), Vector3f(0.f, 0.f, 1.f)); interaction->t = t; interaction->wo = Normalize(-local_ray.Direction()); interaction->uv = Vector2f((hit_p.x() + x_size / 2.f) / x_size, (hit_p.z() + z_size / 2.f) / z_size); interaction->surface = this; // Transform to global space *interaction = TransformInteraction(local_to_world, world_to_local, *interaction); return true; } } } return false; }
bool Rectangle::IntersectP(const Ray &ray, const RayInterval &interval) const { // Compute local ray Ray local_ray = TransformRay(world_to_local, ray); // Check intersection with plane if (std::abs(local_ray.Direction().y()) > EPS) { // Compute intersection with plane float t = -local_ray.Origin().y() * local_ray.InvDirection().y(); // Check boundaries if (interval.Inside(t)) { // Compute intersection point Vector3f hit_p = local_ray(t); // Check hit point inside rectangle if (hit_p.x() > -x_size / 2.f && hit_p.x() < x_size / 2.f && hit_p.z() > -z_size / 2.f && hit_p.z() < z_size / 2.f) { return true; } } } return false; }