Mercurial > projects > ldc
annotate demos/ray.cpp @ 1112:829ac3f30103
Updating revisions.pl.in:
- Change the way the LLVM SVN revision is detected, using `svn info` instead
of `svnversion`. This speeds it up significantly on my machine (especially
when the LLVM SVN checkout isn't in disk cache).
- Add "last changed date" to SVN checkouts too, not just unpacked tarballs
- No longer rely on SVN revision to detect release vs trunk checkouts, treat
release checkout the same as unpacked release tarball. (Except for date
determination, which uses SVN date instead of filesystem date)
author | Frits van Bommel <fvbommel wxs.nl> |
---|---|
date | Fri, 13 Mar 2009 16:18:01 +0100 |
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 } |