annotate demos/ray.d @ 108:288fe1029e1f trunk

[svn r112] Fixed 'case 1,2,3:' style case statements. Fixed a bunch of bugs with return/break/continue in loops. Fixed support for the DMDFE hidden implicit return value variable. This can be needed for some foreach statements where the loop body is converted to a nested delegate, but also possibly returns from the function. Added std.math to phobos. Added AA runtime support code, done ground work for implementing AAs. Several other bugfixes.
author lindquist
date Tue, 20 Nov 2007 05:29:20 +0100
parents 5071469303d4
children 9922b9982552
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
100
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents: 96
diff changeset
1 import std.stdio;
92
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
2
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
3 int atoi(char[] s) {
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
4 int i, fac=1;
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
5 bool neg = (s.length) && (s[0] == '-');
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
6 char[] a = neg ? s[1..$] : s;
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
7 foreach_reverse(c; a) {
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
8 i += (c-'0') * fac;
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
9 fac *= 10;
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
10 }
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
11 return !neg ? i : -i;
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
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
14 pragma(LLVM_internal, "intrinsic", "llvm.sqrt.f64")
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
15 double sqrt(double val);
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
16
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
17 double delta;
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
18 static this() { delta=sqrt(real.epsilon); }
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
19
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
20 struct Vec {
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
21 double x, y, z;
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
22 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
23 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
24 Vec opMul(double a) { return Vec(x*a, y*a, z*a); }
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
25 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
26 Vec unitise() { return opMul(1.0/sqrt(dot(*this))); }
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
27 }
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 Pair(T, U) { T first; U second; }
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
30 typedef Pair!(double, Vec) Hit;
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
31
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
32 struct Ray { Vec orig, dir; }
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
33
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
34 class Scene {
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
35 //abstract void intersect(ref Hit, ref Ray);
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
36 void intersect(ref Hit, ref Ray) {}
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
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
39 class Sphere : Scene {
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
40 Vec center;
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
41 double radius;
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
42 //mixin This!("center, radius");
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
43 this(ref Vec c, double r)
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
44 {
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
45 center = c;
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
46 radius = r;
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 double ray_sphere(ref Ray ray) {
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
49 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
50 if (disc < 0) return double.infinity;
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
51 auto d = sqrt(disc), t2 = b + d;
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
52 if (t2 < 0) return double.infinity;
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
53 auto t1 = b - d;
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
54 return (t1 > 0 ? t1 : t2);
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
55 }
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
56 void intersect(ref Hit hit, ref Ray ray) {
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
57 auto lambda = ray_sphere(ray);
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
58 if (lambda < hit.first)
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
59 hit = Hit(lambda, (ray.orig + lambda*ray.dir - center).unitise);
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
60 }
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
61 }
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
62
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
63 class Group : Scene {
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
64 Sphere bound;
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
65 Scene[] children;
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
66 //mixin This!("bound, children");
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
67 this (Sphere s, Scene[] c)
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
68 {
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
69 bound = s;
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
70 children = c;
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 void intersect(ref Hit hit, ref Ray ray) {
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
73 auto l = bound.ray_sphere(ray);
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
74 if (l < hit.first) foreach (child; children) child.intersect(hit, ray);
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
75 }
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
76 }
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 double ray_trace(ref Vec light, ref Ray ray, Scene s) {
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
79 auto hit=Hit(double.infinity, Vec(0, 0, 0));
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
80 s.intersect(hit, ray);
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
81 if (hit.first == double.infinity) return 0.0;
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
82 auto g = hit.second.dot(light);
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
83 if (g >= 0) return 0.0;
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
84 auto p = ray.orig + ray.dir*hit.first + hit.second*delta;
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
85 auto hit2=Hit(double.infinity, Vec(0, 0, 0));
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
86 s.intersect(hit2, Ray(p, light*-1.0));
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
87 return (hit2.first < double.infinity ? 0 : -g);
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
88 }
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
89
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
90 Scene create(int level, ref Vec c, double r) {
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
91 auto s = new Sphere(c, r);
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
92 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
93 Scene[] children;
61615fa85940 [svn r98] Added support for std.c.stdlib.alloca via pragma(LLVM_internal, "alloca").
lindquist
parents: 92
diff changeset
94 children ~= s;
92
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
95 double rn = 3*r/sqrt(12.0);
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
96 for (int dz=-1; dz<=1; dz+=2)
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
97 for (int dx=-1; dx<=1; dx+=2)
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
98 children~=create(level-1, c + Vec(dx, 1, dz)*rn, r/2);
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
99 return new Group(new Sphere(c, 3*r), children);
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
100 }
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
101
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
102 void main(string[] args) {
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
103 int level = (args.length==3 ? args[1].atoi() : 9),
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
104 n = (args.length==3 ? args[2].atoi() : 512), ss = 4;
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
105 auto light = Vec(-1, -3, 2).unitise();
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
106 auto s=create(level, Vec(0, -1, 0), 1);
100
5071469303d4 [svn r104] TONS OF FIXES.
lindquist
parents: 96
diff changeset
107 writefln("P5\n", n, " ", n, "\n255");
92
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
108 for (int y=n-1; y>=0; --y)
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
109 for (int x=0; x<n; ++x) {
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
110 double g=0;
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
111 for (int d=0; d<ss*ss; ++d) {
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
112 auto dir=Vec(x+(d%ss)*1.0/ss-n/2.0, y+(d/ss)*1.0/ss-n/2.0, n).unitise();
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
113 g += ray_trace(light, Ray(Vec(0, 0, -4), dir), s);
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
114 }
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
115 printf("%c", cast(ubyte)(0.5 + 255.0 * g / (ss*ss)));
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
116 }
70d6113eeb8c [svn r96] Updated to DMD 1.023.
lindquist
parents:
diff changeset
117 }