Пример #1
0
bool Sphere::intersect(Ray& ray, float& tHit, Intersection* intersect) {
    vec3 e = ray.pos;
    vec3 d = ray.dir;

    float a = d*d;
    float b = 2*d*(e - this->center);
    float c = (e - this->center)*(e - this->center) - this->radius*this->radius;

    if (a == 0) {
        std::cout << "Ray is just a point!" << std::endl;
        return false;
    }

    float discriminant = b*b - 4*a*c;

    //float tMin = std::numeric_limits<float>::max();
    if (discriminant >= 0) {
        float tPos = (-b + sqrt(discriminant)) / (2.0f*a);
        float tNeg = (-b - sqrt(discriminant)) / (2.0f*a);

        tHit = /*(tNeg<0 && tPos>0)? tPos :*/ tNeg;
        if (tHit >= ray.tMax || tHit <= ray.tMin) return false;

        intersect->point = vec3(transform * vec4(ray.evaluate(tHit),1),VW);
        intersect->normal  = vec3(transformTI * vec4(intersect->point - this->center, 0),VW).normalize();
        //if (tNeg<0 && tPos>0) {
        //	intersect->normal = -1*intersect->normal;
        //}
        intersect->shape = this;
        return true;
    }
    return false;
}
Пример #2
0
bool Triangle::intersect(Ray& ray, float& tHit, Intersection* intersect) {
    vec3 eye = ray.pos;
    vec3 dir = ray.dir;

    float a = v1[VX] - v2[VX],  d = v1[VX] - v3[VX],   g = dir[VX];
    float b = v1[VY] - v2[VY],  e = v1[VY] - v3[VY],   h = dir[VY];
    float c = v1[VZ] - v2[VZ],  f = v1[VZ] - v3[VZ],   i = dir[VZ];

    float j = v1[VX]-eye[VX];
    float k = v1[VY]-eye[VY];
    float l = v1[VZ]-eye[VZ];

    float m = (a*(e*i - h*f) + b*(g*f - d*i) + c*(d*h - e*g));

    float t = (f*(a*k - j*b) + e*(j*c - a*l) + d*(b*l - k*c))/-m;
    if (t < ray.tMin || t > ray.tMax) return false;

    float gamma = (i*(a*k - j*b) + h*(j*c - a*l) + g*(b*l - k*c)) / m;
    if (gamma < 0 || gamma > 1) return false;

    float beta = (j*(e*i - h*f) + k*(g*f - d*i) + l*(d*h - e*g))/m;
    if (beta < 0 || beta > 1-gamma) return false;

    tHit = t;
    intersect->point = ray.evaluate(t);
    intersect->shape = this;

    float mag = (v1-intersect->point).length() + (v2-intersect->point).length() + (v3-intersect->point).length();

    intersect->normal = (((v1-intersect->point).length()/mag)*n1 + ((v2-intersect->point).length()/mag)*n2 + ((v3-intersect->point).length()/mag)*n3).normalize();

    return true;
}
Пример #3
0
std::unique_ptr<Intersection> Sphere::intersect(const Ray& ray) {
    auto p = ray.p - center;
    auto d = ray.d;

    float dp = d.dot(p);
    float dd = d.dot(d);
    float pp = p.dot(p);

    float discr = (dp*dp) - (dd*(pp-(radius*radius)));

    if (discr < 0) {
        return nullptr;
    } else {
        // Find both intersections
        float t0 = (-dp - sqrt(discr)) / dd;
        float t1 = (-dp + sqrt(discr)) / dd;

        // Entire sphere is behind camera
        if (t1 < 0)
            return nullptr;

        // Front of sphere is behind camera
        float t = t0 < 0 ? t1 : t0;

        // Calculate surface normal
        auto n = (ray.evaluate(t) - center).normalized();

        return std::unique_ptr<Intersection>(new Intersection(this, n, t));
    }
}
Пример #4
0
glm::vec3 Sphere::collisionNormal( const Ray& ray ) const
{
	float time = intersect( ray );
	if( time == inf )
		return glm::vec3();

	return glm::normalize( ray.evaluate( time ) - center );
}
Пример #5
0
Color Scene::shade(const Ray& ray, const Intersection& hit, int depth, bool shadows, bool kd) const {
    auto p = ray.evaluate(hit.t); 
    auto n = hit.normal;

    return (hit.hit)->shade(ray, p, n, light, *this, depth, shadows, kd);
}