fixed Box::Extend(Vec3f&)
[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 < Epsilon )
30 {
31 t = (-B+root)/(2.0f*A);
32 if( t < Epsilon || t > ray.t())
33 return false;
34 }
35
36 ray.setT(t);
37 ray.setHit(this);
38
39 return true;
40 }
41
42 Vec3f
43 Sphere::GetNormal(Ray& ray)
44 {
45 Vec3f p = ray.origin()+ray.direction()*ray.t();
46 Vec3f N = (p-m_center);
47 N.normalize();
48
49 return N;
50 }
51
52 Box
53 Sphere::CalcBounds()
54 {
55 Vec3f min(m_center[0] - m_radius/2, m_center[1] - m_radius/2,
56 m_center[2] - m_radius/2);
57 Vec3f max(m_center[0] + m_radius/2, m_center[1] + m_radius/2,
58 m_center[2] + m_radius/2);
59 return Box(min, max);
60 }
61
62 bool
63 Sphere::InVoxel(const Box& box)
64 {
65 return CalcBounds().Overlaps(box);
66 }
This page took 0.047771 seconds and 5 git commands to generate.