annotate demos/ray.d @ 650:aa6a0b7968f7

Added test case for bug #100 Removed dubious check for not emitting static private global in other modules without access. This should be handled properly somewhere else, it's causing unresolved global errors for stuff that should work (in MiniD)
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Sun, 05 Oct 2008 17:28:15 +0200
parents 718ddecc053c
children eef8ac26c66c
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
165
9922b9982552 [svn r181] Updated the raytracer demo by downs to work with tango :) My quick
lindquist
parents: 100
diff changeset
16 version(LLVMDC)
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 }