nuclear@0: #include nuclear@0: #include "sphere.h" nuclear@0: nuclear@0: Sphere::Sphere() nuclear@0: { nuclear@0: radius = 1.0; nuclear@0: } nuclear@0: nuclear@0: Sphere::Sphere(const Vector3 &pos, float rad) nuclear@0: { nuclear@0: radius = rad; nuclear@0: this->pos = pos; nuclear@0: } nuclear@0: nuclear@0: bool Sphere::intersect(const Ray &inray, HitPoint *pt) const nuclear@0: { nuclear@0: Ray ray = inray.transformed(inv_xform); nuclear@0: nuclear@0: float a = dot_product(ray.dir, ray.dir); nuclear@0: float b = 2.0 * ray.dir.x * (ray.origin.x - pos.x) + nuclear@0: 2.0 * ray.dir.y * (ray.origin.y - pos.y) + nuclear@0: 2.0 * ray.dir.z * (ray.origin.z - pos.z); nuclear@0: float c = dot_product(ray.origin, ray.origin) + dot_product(pos, pos) - nuclear@0: 2.0 * dot_product(ray.origin, pos) - radius * radius; nuclear@0: nuclear@0: float discr = b * b - 4.0 * a * c; nuclear@0: if(discr < 1e-4) nuclear@0: return false; nuclear@0: nuclear@0: float sqrt_discr = sqrt(discr); nuclear@0: float t0 = (-b + sqrt_discr) / (2.0 * a); nuclear@0: float t1 = (-b - sqrt_discr) / (2.0 * a); nuclear@0: nuclear@0: if(t0 < 1e-4) nuclear@0: t0 = t1; nuclear@0: if(t1 < 1e-4) nuclear@0: t1 = t0; nuclear@0: nuclear@0: float t = t0 < t1 ? t0 : t1; nuclear@0: if(t < 1e-4) nuclear@0: return false; nuclear@0: nuclear@0: // fill the HitPoint structure nuclear@0: pt->obj = this; nuclear@0: pt->dist = t; nuclear@0: pt->pos = ray.origin + ray.dir * t; nuclear@0: pt->normal = (pt->pos - pos) / radius; nuclear@0: nuclear@0: pt->pos.transform(xform); nuclear@0: pt->normal.transform(dir_xform); nuclear@0: return true; nuclear@0: }