IntersectionInfo Sphere::rayIntersect(Ray _ray) { Point3f e = _ray.e(); Point3f c = center_; Vector3f d = _ray.d(); float discriminant = dot(d,(e-c))*dot(d,(e-c))- dot(d,d)*(dot((e-c),(e-c))-radius_*radius_); if (discriminant < 0.0) { return IntersectionInfo(0.0, Point3f(), Vector3f(), IntersectionInfo::miss()); } else { float t1 = (dot(d*-1.0,(e-c))+sqrt(discriminant))/dot(d,d); float t2 = (dot(d*-1.0,(e-c))-sqrt(discriminant))/dot(d,d); float t; if (t1 < t2) { t = t1; } else { t = t2; } if (t < _ray.tMin() || t > _ray.tMax()) { return IntersectionInfo(0.0, Point3f(), Vector3f(), IntersectionInfo::miss()); } Point3f p = e + d*t; Vector3f n = 2.0*(p-c); n.normalize(); return IntersectionInfo(t, p, n, IntersectionInfo::hit()); } }
// _____________________________________________________________________________ void UniformGrid::intersectCellShapes(const glm::ivec3& index, const Ray& ray, std::vector<IntersectionInfo>* intersections) const { auto it = m_Shapes.find(index); if (it != m_Shapes.end()) { const size_t numShapes = it->second.size(); for (size_t i = 0; i < numShapes; ++i) { const std::pair<Shape*, uint64_t>& current = it->second.at(i); Mesh* mesh; if ((mesh = dynamic_cast<Mesh*>(current.first))) { Ray transformedRay = mesh->getInverseTransformMatrix() * ray; std::vector<size_t> hits; std::vector<float> b1; std::vector<float> b2; std::vector<REAL> t = intersectTriangles(transformedRay, mesh->getVertices(), current.second, current.second + 3, &hits, &b1, &b2); if (t.size() == 0) { continue; } float tVal = t[0]; glm::vec4 position = ray.origin() + static_cast<float>(tVal) * ray.direction(); const std::vector<vec3>& normals = mesh->getNormals(); float beta = b1[0]; float gamma = b2[0]; float alpha = 1 - beta - gamma; // printf("alpha/beta/gamma(%.2f/%.2f/%.2f)\n", alpha, beta, gamma); intersections->push_back(IntersectionInfo(tVal, position, glm::normalize(mesh->getTransformMatrix() * glm::vec4( ((alpha * normals[current.second]) + (beta * normals[current.second + 1]) + (gamma * normals[current.second + 2])), 0.0f)), mesh->getMaterialPtr(), glm::vec2(0.0f))); } else { intersections->push_back(current.first->getIntersectionInfo(ray)); } } } }