1 #ifndef QUADRIC_HXX
2 #define QUADRIC_HXX
3
4 #include "Primitive.hxx"
5 #include "Box.hxx"
6
7 class Quadric : public Primitive
8 {
9 float a, b, c, d, e, f, g, h, i, j,
10 alpha, beta, gamma, p, radicand, t[2];
11 int num;
12 public:
13 Quadric(float a, float b, float c, float d, float e, float f, float g,
14 float h, float i, float j, Shader *shader, PhotonDistributor *photon_distributor)
15 : Primitive(shader, photon_distributor),a(a),b(b),c(c),d(d),e(e),f(f),g(g),h(h),i(i),j(j)
16 {};
17
18 virtual ~Quadric(){};
19
20 virtual bool Intersect(Ray &ray)
21 {
22 alpha = a * ray.dir.x * ray.dir.x
23 + b * ray.dir.y * ray.dir.y
24 + c * ray.dir.z * ray.dir.z
25 + d * ray.dir.x * ray.dir.y
26 + e * ray.dir.x * ray.dir.z
27 + f * ray.dir.y * ray.dir.z;
28
29 beta = 2.0 * a * ray.org.x * ray.dir.x
30 + 2.0 * b * ray.org.y * ray.dir.y
31 + 2.0 * c * ray.org.z * ray.dir.z
32 + d * ray.org.x * ray.dir.y
33 + d * ray.org.y * ray.dir.x
34 + e * ray.org.x * ray.dir.z
35 + e * ray.org.z * ray.dir.x
36 + f * ray.org.y * ray.dir.z
37 + f * ray.org.z * ray.dir.y
38 + g * ray.dir.x
39 + h * ray.dir.y
40 + i * ray.dir.z;
41
42 gamma = a * ray.org.x * ray.org.x
43 + b * ray.org.y * ray.org.y
44 + c * ray.org.z * ray.org.z
45 + d * ray.org.x * ray.org.y
46 + e * ray.org.x * ray.org.z
47 + f * ray.org.y * ray.org.z
48 + g * ray.org.x
49 + h * ray.org.y
50 + i * ray.org.z
51 + j;
52
53 // Apply the p-q-Formula:
54 p = beta / (2.0 * alpha);
55 radicand = p * p - gamma / alpha;
56
57 if (radicand >= 0.0)
58 {
59 // We have two solutions. The Sqrt is only calculated once:
60 radicand = sqrt(radicand);
61 t[0] = -p + radicand;
62 t[1] = -p - radicand;
63
64 // Check the closer intersection point and take it if necessary
65 num = t[1] < t[0];
66 if (t[num] < ray.t && t[num] > Epsilon)
67 {
68 ray.t = t[num];
69 ray.hit = this;
70 return true;
71 }
72
73 // Check the farer intersection point and take it if necessary
74 num = !num;
75 if (t[num] < ray.t && t[num] > Epsilon)
76 {
77 ray.t = t[num];
78 ray.hit = this;
79 return true;
80 }
81 }
82
83 // We could not find any intersection point
84 return false;
85 };
86
87 virtual Vec3f GetNormal(Ray &ray)
88 {
89 Vec3f p = ray.org + ray.t * ray.dir;
90 Vec3f normal = Vec3f(2 * a * p.x + d * p.y + e * p.z + g,
91 2 * b * p.y + d * p.x + f * p.z + h,
92 2 * c * p.z + e * p.x + f * p.y + i);
93 Normalize(normal);
94 return normal;
95 };
96
97 virtual Box CalcBounds()
98 {
99 // Return real bounding boxes later on (TODO)
100 return Box();
101 }
102 };
103
104 #endif
syntax highlighted by Code2HTML, v. 0.9.1