still broken ReflectiveEyeLightShader, saving it for later
[MicroTrace.git] / Sphere.cxx
1 #include "Sphere.hxx"
2
3 Sphere::Sphere(const Vec3f& center, float radius, Shader* shader)
4 : Primitive(shader),
5 m_center(center),
6 m_radius(radius)
7 {
8 }
9
10 Sphere::~Sphere()
11 {
12 }
13
14 bool
15 Sphere::Intersect(Ray& ray)
16 {
17 float A = ray.direction().dot(ray.direction());
18 float C = (ray.origin()-m_center).dot(ray.origin()-m_center) - m_radius*m_radius;
19 float B = 2 * ray.direction().dot(ray.origin()-m_center);
20
21 if( B*B-4*A*C < 0 )
22 return false;
23
24 float root = sqrtf(B*B-4*A*C);
25 float t = (-B-root)/(2.0f*A);
26 if(t > ray.t())
27 return false;
28
29 if( t < 1e-6 )
30 {
31 t = (-B+root)/(2.0f*A);
32 if( t < 1e-6 || t > ray.t())
33 return false;
34 }
35 ray.setT(t);
36 return true;
37 }
38
39 Vec3f
40 Sphere::GetNormal(Ray& ray)
41 {
42 // We don't want to modify the ray (probably this is not needed, but I am
43 // too lazy to think about it now ...)
44 Ray tempRay = ray;
45
46 // Surface normal is the difference between intersection and center point
47 if(Intersect(tempRay)) {
48 // intersection point
49 Vec3f i = tempRay.origin() + tempRay.direction() * (tempRay.t() - Epsilon);
50 // normal
51 Vec3f n = (i - m_center);
52 n.normalize();
53 return n;
54 } else {
55 // no intersection with ray, so no surface normal
56 return Vec3f(0,0,0);
57 }
58 }
This page took 0.04812 seconds and 5 git commands to generate.