Пример #1
0
    void Sphere::raycast(const Raycast& ray, RayHitList& reports) const
    {
        double a, b, c;
        params(ray, a, b, c);
        double discr = b*b - 4*a*c;
        if(discr > 0.0)
        {
            double disrcSqrt = glm::sqrt(discr);

            double t1 = (-b - disrcSqrt) / (2 * a);
            if(0.0 < t1 && t1 < ray.limit)
            {
                glm::dvec3 pt = ray.origin + ray.direction*t1;
                glm::dvec3 n = glm::normalize(pt - _center);
                reports.add(t1, ray, pt, n,
                            RayHitReport::NO_TEXCOORD,
                             _coating.get());
            }

            double t2 = (-b + disrcSqrt) / (2 * a);
            if(0.0 < t2 && t2 < ray.limit)
            {
                glm::dvec3 pt = ray.origin + ray.direction*t2;
                glm::dvec3 n = glm::normalize(pt - _center);
                reports.add(t2, ray, pt, n,
                            RayHitReport::NO_TEXCOORD,
                             _coating.get());
            }
        }
        else if(discr == 0.0)
        {
            double t = -b / (2 * a);
            if(0.0 < t && t < ray.limit)
            {
                glm::dvec3 pt = ray.origin + ray.direction*t;
                glm::dvec3 n = glm::normalize(pt - _center);
                reports.add(t, ray, pt, n,
                            RayHitReport::NO_TEXCOORD,
                             _coating.get());
            }
        }
    }
Пример #2
0
    void Disk::raycast(const Raycast& ray, RayHitList& reports) const
    {
        glm::dvec3 orig = glm::dvec3(_invTransform * glm::dvec4(ray.origin, 1.0));
        glm::dvec3 dir = glm::dvec3(_invTransform * glm::dvec4(ray.direction, 0.0));


        double dirDotNorm = glm::dot(_normal, dir);
        if(dirDotNorm != 0.0)
        {
            double t = -(glm::dot(_normal, orig) + _d) / dirDotNorm;
            if(0.0 < t && t < ray.limit)
            {
                if(glm::distance(orig + dir * t, _center) < _radius)
                {
                    glm::dvec3 pt = ray.origin + ray.direction * t;
                    reports.add(t, pt, _transformN,
                                RayHitReport::NO_TEXCOORD,
                                _coating.get(),
                                _innerMat.get(),
                                _outerMat.get());
                }
            }
        }
    }
Пример #3
0
    // ref : http://marctenbosch.com/photon/mbosch_intersection.pdf
    void Quadric::raycast(const Raycast& ray, RayHitList& reports) const
    {
        double a, b, c;
        params(ray, a, b, c);

        if(a != 0.0)
        {
            double dscr = b*b - 4*a*c;
            if(dscr > 0.0)
            {
                double dsrcSqrt = glm::sqrt(dscr);

                {
                    double t = (-b - dsrcSqrt) / (2 * a);
                    if(0.0 < t && t < ray.limit)
                    {
                        glm::dvec3 pt1 = ray.origin + ray.direction*t;
                        glm::dvec3 n1 =  computeNormal(_q, pt1);
                        reports.add(t, ray, pt1, n1,
                                    RayHitReport::NO_TEXCOORD,
                                    _coating.get());
                    }
                }

                {
                    double t = (-b + dsrcSqrt) / (2 * a);
                    if(0.0 < t && t < ray.limit)
                    {
                        glm::dvec3 pt2 = ray.origin + ray.direction*t;
                        glm::dvec3 n2 =  computeNormal(_q, pt2);
                        reports.add(t, ray, pt2, n2,
                                    RayHitReport::NO_TEXCOORD,
                                    _coating.get());
                    }
                }
            }
            else if (dscr == 0.0)
            {
                double t = -b / (2 * a);
                if(0.0 < t && t < ray.limit)
                {
                    glm::dvec3 pt = ray.origin + ray.direction*t;
                    glm::dvec3 n =  computeNormal(_q, pt);
                    reports.add(t, ray, pt, n,
                                RayHitReport::NO_TEXCOORD,
                                _coating.get());
                }
            }
        }
        else
        {
            if(b != 0.0)
            {
                double t = -c / b;
                if(0.0 < t && t < ray.limit)
                {
                    glm::dvec3 pt = ray.origin + ray.direction * t;
                    glm::dvec3 n =  computeNormal(_q, pt);
                    reports.add(t, ray, pt, n,
                                RayHitReport::NO_TEXCOORD,
                                _coating.get());
                }
            }
        }
    }