annotate demos/ray.d @ 883:b52d5de7783f

GC defines and linkage changes.
author Christian Kamm <kamm incasoftware de>
date Thu, 08 Jan 2009 18:20:02 +0100
parents eef8ac26c66c
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
165
9922b9982552 [svn r181] Updated the raytracer demo by downs to work with tango :) My quick
lindquist
parents: 100
diff changeset
1 import tango.stdc.stdio;
9922b9982552 [svn r181] Updated the raytracer demo by downs to work with tango :) My quick
lindquist
parents: 100
diff changeset
2
9922b9982552 [svn r181] Updated the raytracer demo by downs to work with tango :) My quick
lindquist
parents: 100
diff changeset
3 alias char[] string;
92
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
4
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
5 int atoi(char[] s) {
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
6 int i, fac=1;
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
7 bool neg = (s.length) && (s[0] == '-');
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
8 char[] a = neg ? s[1..$] : s;
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
9 foreach_reverse(c; a) {
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
10 i += (c-'0') * fac;
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
11 fac *= 10;
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
12 }
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
13 return !neg ? i : -i;
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
14 }
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
15
664
eef8ac26c66c Some missed LLVMDC -> LDC.
Christian Kamm <kamm incasoftware de>
parents: 620
diff changeset
16 version(LDC)
165
9922b9982552 [svn r181] Updated the raytracer demo by downs to work with tango :) My quick
lindquist
parents: 100
diff changeset
17 {
620
718ddecc053c Fix downs' raytracer demo to use new intrinsics.
Christian Kamm <kamm incasoftware de>
parents: 166
diff changeset
18 pragma(intrinsic, "llvm.sqrt.f64")
92
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
19 double sqrt(double val);
165
9922b9982552 [svn r181] Updated the raytracer demo by downs to work with tango :) My quick
lindquist
parents: 100
diff changeset
20 }
9922b9982552 [svn r181] Updated the raytracer demo by downs to work with tango :) My quick
lindquist
parents: 100
diff changeset
21 else
9922b9982552 [svn r181] Updated the raytracer demo by downs to work with tango :) My quick
lindquist
parents: 100
diff changeset
22 {
9922b9982552 [svn r181] Updated the raytracer demo by downs to work with tango :) My quick
lindquist
parents: 100
diff changeset
23 import tango.stdc.math;
9922b9982552 [svn r181] Updated the raytracer demo by downs to work with tango :) My quick
lindquist
parents: 100
diff changeset
24 }
92
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
25
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
26 double delta;
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
27 static this() { delta=sqrt(real.epsilon); }
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
28
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
29 struct Vec {
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
30 double x, y, z;
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
31 Vec opAdd(ref Vec other) { return Vec(x+other.x, y+other.y, z+other.z); }
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
32 Vec opSub(ref Vec other) { return Vec(x-other.x, y-other.y, z-other.z); }
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
33 Vec opMul(double a) { return Vec(x*a, y*a, z*a); }
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
34 double dot(ref Vec other) { return x*other.x+y*other.y+z*other.z; }
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
35 Vec unitise() { return opMul(1.0/sqrt(dot(*this))); }
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
36 }
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
37
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
38 struct Pair(T, U) { T first; U second; }
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
39 typedef Pair!(double, Vec) Hit;
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
40
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
41 struct Ray { Vec orig, dir; }
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
42
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
43 class Scene {
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
44 //abstract void intersect(ref Hit, ref Ray);
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
45 void intersect(ref Hit, ref Ray) {}
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
46 }
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
47
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
48 class Sphere : Scene {
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
49 Vec center;
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
50 double radius;
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
51 //mixin This!("center, radius");
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
52 this(ref Vec c, double r)
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
53 {
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
54 center = c;
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
55 radius = r;
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
56 }
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
57 double ray_sphere(ref Ray ray) {
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
58 auto v = center - ray.orig, b = v.dot(ray.dir), disc=b*b - v.dot(v) + radius*radius;
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
59 if (disc < 0) return double.infinity;
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
60 auto d = sqrt(disc), t2 = b + d;
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
61 if (t2 < 0) return double.infinity;
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
62 auto t1 = b - d;
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
63 return (t1 > 0 ? t1 : t2);
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
64 }
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
65 void intersect(ref Hit hit, ref Ray ray) {
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
66 auto lambda = ray_sphere(ray);
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
67 if (lambda < hit.first)
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
68 hit = Hit(lambda, (ray.orig + lambda*ray.dir - center).unitise);
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
69 }
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
70 }
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
71
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
72 class Group : Scene {
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
73 Sphere bound;
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
74 Scene[] children;
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
75 //mixin This!("bound, children");
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
76 this (Sphere s, Scene[] c)
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
77 {
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
78 bound = s;
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
79 children = c;
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
80 }
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
81 void intersect(ref Hit hit, ref Ray ray) {
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
82 auto l = bound.ray_sphere(ray);
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
83 if (l < hit.first) foreach (child; children) child.intersect(hit, ray);
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
84 }
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
85 }
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
86
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
87 double ray_trace(ref Vec light, ref Ray ray, Scene s) {
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
88 auto hit=Hit(double.infinity, Vec(0, 0, 0));
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
89 s.intersect(hit, ray);
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
90 if (hit.first == double.infinity) return 0.0;
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
91 auto g = hit.second.dot(light);
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
92 if (g >= 0) return 0.0;
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
93 auto p = ray.orig + ray.dir*hit.first + hit.second*delta;
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
94 auto hit2=Hit(double.infinity, Vec(0, 0, 0));
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
95 s.intersect(hit2, Ray(p, light*-1.0));
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
96 return (hit2.first < double.infinity ? 0 : -g);
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
97 }
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
98
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
99 Scene create(int level, ref Vec c, double r) {
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
100 auto s = new Sphere(c, r);
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
101 if (level == 1) return s;
94
61615fa85940 [svn r98] Added support for std.c.stdlib.alloca via pragma(LLVM_internal, "alloca").
lindquist
parents: 92
diff changeset
102 Scene[] children;
61615fa85940 [svn r98] Added support for std.c.stdlib.alloca via pragma(LLVM_internal, "alloca").
lindquist
parents: 92
diff changeset
103 children ~= s;
92
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
104 double rn = 3*r/sqrt(12.0);
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
105 for (int dz=-1; dz<=1; dz+=2)
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
106 for (int dx=-1; dx<=1; dx+=2)
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
107 children~=create(level-1, c + Vec(dx, 1, dz)*rn, r/2);
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
108 return new Group(new Sphere(c, 3*r), children);
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
109 }
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
110
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
111 void main(string[] args) {
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
112 int level = (args.length==3 ? args[1].atoi() : 9),
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
113 n = (args.length==3 ? args[2].atoi() : 512), ss = 4;
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
114 auto light = Vec(-1, -3, 2).unitise();
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
115 auto s=create(level, Vec(0, -1, 0), 1);
166
a2c4dc388d5e [svn r182] Oups, the PGM output for the raytracer demo was borked.
lindquist
parents: 165
diff changeset
116 printf("P5\n%d %d\n255\n", n,n);
92
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
117 for (int y=n-1; y>=0; --y)
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
118 for (int x=0; x<n; ++x) {
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
119 double g=0;
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
120 for (int d=0; d<ss*ss; ++d) {
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
121 auto dir=Vec(x+(d%ss)*1.0/ss-n/2.0, y+(d/ss)*1.0/ss-n/2.0, n).unitise();
165
9922b9982552 [svn r181] Updated the raytracer demo by downs to work with tango :) My quick
lindquist
parents: 100
diff changeset
122 g += ray_trace(light, Ray(Vec(0, 0, -4), dir), s);
92
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
123 }
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
124 printf("%c", cast(ubyte)(0.5 + 255.0 * g / (ss*ss)));
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
125 }
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
126 }