예제 #1
0
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());
    }
}
예제 #2
0
// _____________________________________________________________________________
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));
            }
        }
    }
}