[svn] r5976: nemerle/trunk/snippets/raytracer/ray-hand-opt.n
malekith
svnadmin at nemerle.org
Mon Nov 28 13:01:23 CET 2005
Log:
Transform matching to vcalls, this gives 10% speedup (vs optimized matching).
Author: malekith
Date: Mon Nov 28 13:01:22 2005
New Revision: 5976
Modified:
nemerle/trunk/snippets/raytracer/ray-hand-opt.n
Modified: nemerle/trunk/snippets/raytracer/ray-hand-opt.n
==============================================================================
--- nemerle/trunk/snippets/raytracer/ray-hand-opt.n (original)
+++ nemerle/trunk/snippets/raytracer/ray-hand-opt.n Mon Nov 28 13:01:22 2005
@@ -21,16 +21,40 @@
(1 / Sqrt (this ** this)) * this
-variant Scene
- | Sphere { m : Vec; r : double; }
- | Group { m : Vec; r : double; l : list [Scene]; }
+abstract class Scene
+ public abstract intersect (orig : Vec, dir : Vec, first : double * Vec) : double * Vec
+
+ [Record] \
+ internal sealed class Sphere : Scene
+ public center : Vec
+ public radius : double
+ public override intersect (orig : Vec, dir : Vec, first : double * Vec) : double * Vec
+ def l = first [0]
+ def l' = M.ray_sphere (orig, dir, center, radius)
+ if (l' >= l) first
+ else (l', (orig + l' * dir - center).Unitise ())
+
+ [Record] \
+ internal sealed class Group : Scene
+ public center : Vec
+ public radius : double
+ public scenes : list [Scene]
+
+ public override intersect (orig : Vec, dir : Vec, first : double * Vec) : double * Vec
+ def l = first [0]
+ def l' = M.ray_sphere (orig, dir, center, radius)
+ if (l' >= l) first
+ else
+ mutable acc = first
+ foreach (s in scenes)
+ acc = s.intersect (orig, dir, acc)
+ acc
module M
delta = 1.49011611938476562e-08
inf : double = 1.0 / 0.0
-
- ray_sphere (orig : Vec, dir : Vec, center : Vec, radius : double) : double
+ internal ray_sphere (orig : Vec, dir : Vec, center : Vec, radius : double) : double
def v = center - orig
def b = v ** dir
def disc = b * b - (v ** v) + radius * radius
@@ -43,36 +67,15 @@
else if (t1 > 0) t1
else t2
- intersect (orig : Vec, dir : Vec, scene : Scene, first : double * Vec) : double * Vec
- def l = first [0]
- match (scene)
- | Scene.Sphere as s =>
- def center = s.m
- def radius = s.r
- def l' = ray_sphere (orig, dir, center, radius)
- if (l' >= l) first
- else (l', (orig + l' * dir - center).Unitise ())
- | Scene.Group as g =>
- def center = g.m
- def radius = g.r
- def scenes = g.l
- def l' = ray_sphere (orig, dir, center, radius)
- if (l' >= l) first
- else
- mutable acc = first
- foreach (s in scenes)
- acc = intersect (orig, dir, s, acc)
- acc
-
ray_trace (light:Vec, orig:Vec, dir:Vec, scene:Scene) : double
- def (lambda, normal) = intersect (orig, dir, scene, (inf, Vec()))
+ def (lambda, normal) = scene.intersect (orig, dir, (inf, Vec()))
if (lambda == inf) 0.0
else
def g = normal ** light
if (g >= 0) 0.0
else
def p = orig + lambda * dir + delta * normal
- if ((intersect (p, -1 * light, scene, (inf,Vec()))) [0] < inf) 0.0
+ if ((scene.intersect (p, -1 * light, (inf,Vec()))) [0] < inf) 0.0
else -g
internal main (level : int, n : int) : void
More information about the svn
mailing list