Mercurial > projects > ldc
annotate demos/ray.cpp @ 618:c9aa338280ed
Removed some excessive llvm type logging
author | tomas@myhost |
---|---|
date | Sun, 28 Sep 2008 15:22:39 +0200 |
parents | 90522b72128a |
children |
rev | line source |
---|---|
180
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
1 #include <list> |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
2 #include <iostream> |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
3 #include <limits> |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
4 #include <cmath> |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
5 #include <cstdlib> |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
6 |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
7 using namespace std; |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
8 |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
9 numeric_limits<double> real; |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
10 double delta = sqrt(real.epsilon()), infinity = real.infinity(); |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
11 |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
12 struct Vec { |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
13 double x, y, z; |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
14 Vec(double x2, double y2, double z2) : x(x2), y(y2), z(z2) {} |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
15 }; |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
16 Vec operator+(const Vec &a, const Vec &b) |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
17 { return Vec(a.x+b.x, a.y+b.y, a.z+b.z); } |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
18 Vec operator-(const Vec &a, const Vec &b) |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
19 { return Vec(a.x-b.x, a.y-b.y, a.z-b.z); } |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
20 Vec operator*(double a, const Vec &b) { return Vec(a*b.x, a*b.y, a*b.z); } |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
21 double dot(const Vec &a, const Vec &b) { return a.x*b.x + a.y*b.y + a.z*b.z; } |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
22 Vec unitise(const Vec &a) { return (1 / sqrt(dot(a, a))) * a; } |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
23 |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
24 typedef pair<double, Vec> Hit; |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
25 |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
26 struct Ray { |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
27 Vec orig, dir; |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
28 Ray(const Vec &o, const Vec &d) : orig(o), dir(d) {} |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
29 }; |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
30 |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
31 struct Scene { |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
32 virtual ~Scene() {}; |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
33 virtual void intersect(Hit &, const Ray &) const = 0; |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
34 }; |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
35 |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
36 struct Sphere : public Scene { |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
37 Vec center; |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
38 double radius; |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
39 |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
40 Sphere(Vec c, double r) : center(c), radius(r) {} |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
41 ~Sphere() {} |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
42 |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
43 double ray_sphere(const Ray &ray) const { |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
44 Vec v = center - ray.orig; |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
45 double b = dot(v, ray.dir), disc = b*b - dot(v, v) + radius * radius; |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
46 if (disc < 0) return infinity; |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
47 double d = sqrt(disc), t2 = b + d; |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
48 if (t2 < 0) return infinity; |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
49 double t1 = b - d; |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
50 return (t1 > 0 ? t1 : t2); |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
51 } |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
52 |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
53 void intersect(Hit &hit, const Ray &ray) const { |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
54 double lambda = ray_sphere(ray); |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
55 if (lambda >= hit.first) return; |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
56 hit = Hit(lambda, unitise(ray.orig + lambda*ray.dir - center)); |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
57 } |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
58 }; |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
59 |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
60 typedef list<Scene *> Scenes; |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
61 struct Group : public Scene { |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
62 Sphere bound; |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
63 Scenes child; |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
64 |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
65 Group(Sphere b, Scenes c) : bound(b), child(c) {} |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
66 ~Group() { |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
67 for (Scenes::const_iterator it=child.begin(); it!=child.end(); ++it) |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
68 delete *it; |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
69 } |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
70 |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
71 void intersect(Hit &hit, const Ray &ray) const { |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
72 double l = bound.ray_sphere(ray); |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
73 if (l < hit.first) |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
74 for (Scenes::const_iterator it=child.begin(); it!=child.end(); ++it) |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
75 (*it)->intersect(hit, ray); |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
76 } |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
77 }; |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
78 |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
79 Hit intersect(const Ray &ray, const Scene &s) { |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
80 Hit res = Hit(infinity, Vec(0, 0, 0)); |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
81 s.intersect(res, ray); |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
82 return res; |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
83 } |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
84 |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
85 double ray_trace(const Vec &light, const Ray &ray, const Scene &s) { |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
86 Hit hit = intersect(ray, s); |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
87 if (hit.first == infinity) return 0; |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
88 double g = dot(hit.second, light); |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
89 if (g >= 0) return 0.; |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
90 Vec p = ray.orig + hit.first*ray.dir + delta*hit.second; |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
91 return (intersect(Ray(p, -1. * light), s).first < infinity ? 0 : -g); |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
92 } |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
93 |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
94 Scene *create(int level, const Vec &c, double r) { |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
95 Scene *s = new Sphere(c, r); |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
96 if (level == 1) return s; |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
97 Scenes child; |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
98 child.push_back(s); |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
99 double rn = 3*r/sqrt(12.); |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
100 for (int dz=-1; dz<=1; dz+=2) |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
101 for (int dx=-1; dx<=1; dx+=2) |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
102 child.push_back(create(level-1, c + rn*Vec(dx, 1, dz), r/2)); |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
103 return new Group(Sphere(c, 3*r), child); |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
104 } |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
105 |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
106 int main(int argc, char *argv[]) { |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
107 int level = 6, n = 512, ss = 4; |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
108 if (argc == 2) level = atoi(argv[1]); |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
109 Vec light = unitise(Vec(-1, -3, 2)); |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
110 Scene *s(create(level, Vec(0, -1, 0), 1)); |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
111 cout << "P5\n" << n << " " << n << "\n255\n"; |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
112 for (int y=n-1; y>=0; --y) |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
113 for (int x=0; x<n; ++x) { |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
114 double g=0; |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
115 for (int dx=0; dx<ss; ++dx) |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
116 for (int dy=0; dy<ss; ++dy) { |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
117 Vec dir(unitise(Vec(x+dx*1./ss-n/2., y+dy*1./ss-n/2., n))); |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
118 g += ray_trace(light, Ray(Vec(0, 0, -4), dir), *s); |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
119 } |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
120 cout << char(int(.5 + 255. * g / (ss*ss))); |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
121 } |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
122 delete s; |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
123 return 0; |
90522b72128a
[svn r196] Added C++ version of the ray demo for comparing.
lindquist
parents:
diff
changeset
|
124 } |