MODULE srVoxel;
IMPORT srBase, Math, srMath, srE, srHex,Out := KernelLog;
TYPE SREAL=srBase.SREAL;
TYPE PT=srBase.PT;
TYPE Ray = srBase.Ray;
TYPE Voxel = srBase.Voxel;
TYPE ColoredVox* = OBJECT(Voxel);
VAR
r, g, b: SREAL;
PROCEDURE SetColor* (red, green, blue : SREAL);
BEGIN
r := srBase.clamp(red );
g := srBase.clamp(green );
b := srBase.clamp(blue );
END SetColor;
PROCEDURE Shade (VAR ray: Ray);
BEGIN
ray.r := ray.r + r*ray.ra;
ray.g := ray.g + g*ray.ga;
ray.b := ray.b + b*ray.ba;
ray.ra := 0;
ray.ga := 0;
ray.ba := 0;
END Shade;
END ColoredVox;
TYPE GoorowVox* = OBJECT(Voxel);
VAR
r, g, b: SREAL;
PROCEDURE Shade (VAR ray: Ray);
BEGIN
ray.r := ray.r + ray.lxyz.x*ray.ra;
ray.g := ray.g + ray.lxyz.y*ray.ga;
ray.b := ray.b + ray.lxyz.z*ray.ba;
ray.ra := 0;
ray.ga := 0;
ray.ba := 0;
ray.a :=0;
END Shade;
END GoorowVox;
TYPE LitVox* = OBJECT(Voxel);
VAR
r, g, b, nx, ny, nz: SREAL;
PROCEDURE SetColor* (red, green, blue : SREAL);
BEGIN
r := srBase.clamp(red);
g := srBase.clamp(green);
b := srBase.clamp(blue);
END SetColor;
PROCEDURE Shade (VAR ray: Ray);
VAR
x,y,z,dotrl: SREAL;
BEGIN
x := 1/2 - ray.lxyz.x; y := 1/2 - ray.lxyz.y; z := 1/2 - ray.lxyz.z;
srBase.normalize(x,y,z);
dotrl :=x*srBase.light.x + y*srBase.light.y + z*srBase.light.z;
IF dotrl > 0 THEN
ray.r := ray.r +(r*dotrl)*ray.ra ;
ray.g := ray.g + (g*dotrl)*ray.ga;
ray.b := ray.b + (b*dotrl)*ray.ba;
END;
ray.ra := 0;
ray.ga := 0;
ray.ba := 0;
ray.a := 0;
END Shade;
END LitVox;
TYPE ColoredMVox* = OBJECT(Voxel);
VAR
r, g, b, mf, a: SREAL;
PROCEDURE SetColor*(red, green, blue, mfraction: SREAL);
BEGIN
mf := srBase.clamp(mfraction);
a := mf;
r := srBase.clamp(red)*a;
g := srBase.clamp(green)*a;
b := srBase.clamp(blue)*a;
END SetColor;
PROCEDURE Shade (VAR ray: Ray);
VAR
dr, dg, db: SREAL;
BEGIN
dr := r*ray.ra;
dg := g*ray.ga;
db := b*ray.ba;
ray.r := ray.r + dr;
ray.g := ray.g + dg;
ray.b := ray.b + db;
ray.ra := ray.ra - a*(dg+db);
ray.ga := ray.ga - a*(dr+db);
ray.ba := ray.ba - a*(dr+dg);
ray.a := (ray.ra+ray.ga+ray.ba)/3;
mirror(ray);
END Shade;
END ColoredMVox;
TYPE DiffuseMVox* = OBJECT(Voxel);
VAR
r, g, b, mf, a: SREAL;
PROCEDURE Shade (VAR ray: Ray);
VAR
nx, ny, nz: INTEGER;
dot: SREAL;
inside: BOOLEAN;
BEGIN
CASE ray.face OF
0: inside := TRUE
|1: nx := -1
|2: ny := -1
|3: nz := -1
|4: nx := 1
|5: ny := 1
|6: nz := 1
ELSE
END;
IF inside THEN dot := 0 ELSE dot := ABS(nx*ray.dxyz.x + ny*ray.dxyz.y+ nz*ray.dxyz.z) END;
ray.ra := dot*ray.ra- 0.3;
ray.ga := dot*ray.ga- 0.3;
ray.ba := dot*ray.ba- 0.3;
ray.a := (ray.ra+ray.ga+ray.ba)/3;
mirror(ray);
END Shade;
END DiffuseMVox;
TYPE DiffuseSphMVox* = OBJECT(ColoredVox);
VAR
mf, a: SREAL;
PROCEDURE Shade(VAR ray: Ray);
VAR
nx, ny, nz: SREAL;
dot: SREAL;
inside: BOOLEAN;
BEGIN
nx := 1/2 - ray.lxyz.x; ny := 1/2-ray.lxyz.y; nz := 1/2-ray.lxyz.z;
srBase.normalize(nx,ny, nz);
IF inside THEN dot := 0 ELSE dot := ABS(nx*ray.dxyz.x + ny*ray.dxyz.y+ nz*ray.dxyz.z) END;
ray.a := dot*ray.a/2;
ray.ra := dot*ray.ra/2;
ray.ga := dot*ray.ga/2;
ray.ba := dot*ray.ba/2;
mirror(ray);
END Shade;
END DiffuseSphMVox;
TYPE DiffuseSphVox* = OBJECT(ColoredVox);
VAR
mf, a: SREAL;
PROCEDURE Shade(VAR ray: Ray);
VAR
dot: SREAL;
p: srBase.PT;
BEGIN
p.x:= 1/2 - ray.lxyz.x; p.y:= 1/2 - ray.lxyz.y; p.z:= 1/2 - ray.lxyz.z;
srBase.normalizePT(p);
dot := ABS(p.x*ray.dxyz.x + p.y*ray.dxyz.y+ p.z*ray.dxyz.z);
ray.r := ray.r + r * ray.ra*dot;
ray.g := ray.g + g * ray.ga*dot;
ray.b := ray.b + b * ray.ba*dot;
ray.ra := 0;
ray.ga := 0;
ray.ba := 0;
ray.a := 0;
END Shade;
END DiffuseSphVox;
TYPE AlphaVox* = OBJECT(Voxel);
VAR
r, g, b, ra, ga, ba: SREAL;
PROCEDURE SetColor* (red, green, blue, alpha : SREAL);
BEGIN
r := srBase.clamp(red * alpha);
g := srBase.clamp(green * alpha);
b := srBase.clamp(blue * alpha);
END SetColor;
PROCEDURE Shade (VAR ray: Ray);
VAR
dr, dg, db: SREAL;
BEGIN
dr := r*ray.ra;
dg := g*ray.ga;
db := b*ray.ba;
ray.r := ray.r + dr;
ray.g := ray.g + dg;
ray.b := ray.b + db;
ray.ra := ray.ra - (dg+db)/2;
ray.ga := ray.ga - (dr+db)/2;
ray.ba := ray.ba - (dr+dg)/2;
ray.a := ray.a -(dr+dg+db)/3;
ray.length := ray.length + ray.scale;
END Shade;
END AlphaVox;
TYPE TransparaVox*=OBJECT(Voxel);
VAR
r, g, b, black: SREAL;
PROCEDURE SetColor* (red, green, blue,bl : SREAL);
BEGIN
r := red;
g := green;
b := blue;
black:=bl;
passable := TRUE;
END SetColor;
PROCEDURE Shade (VAR ray: Ray);
VAR
depth: SREAL;
exit:PT;
dr,dg,db,dblack: SREAL;
BEGIN
exit:=srBase.Exit(ray);
depth:=srBase.distsquared(ray.lxyz,exit);
dr := r*depth;
dg := g*depth;
db := b*depth;
dblack:=black*depth;
ray.r := ray.r + dr;
ray.g := ray.g + dg;
ray.b := ray.b + db;
ray.ra := ray.ra - dr-dblack;
ray.ga := ray.ga - dg-dblack;
ray.ba := ray.ba - db-dblack;
srBase.clamp3(ray.ra,ray.ga,ray.ba);
ray.a := (ray.ra+ray.ga+ray.ba)/3;
END Shade;
END TransparaVox;
TYPE RainbowVox*=OBJECT(Voxel);
VAR
r, g, b, black: SREAL;
PROCEDURE SetColor* (red, green, blue,bl : SREAL);
BEGIN
r := red;
g := green;
b := blue;
black:=bl;
passable := TRUE;
END SetColor;
PROCEDURE Shade (VAR ray: Ray);
VAR
depth: SREAL;
exit:PT;
dr,dg,db,dblack: SREAL;
BEGIN
exit:=srBase.Exit(ray);
depth:=srBase.distsquared(ray.lxyz,exit);
dr := ABS(r*depth*ray.dxyz.x);
dg := ABS(g*depth*ray.dxyz.y);
db := ABS(b*depth*ray.dxyz.z);
dblack:=black*depth;
ray.r := ray.r + dr;
ray.g := ray.g + dg;
ray.b := ray.b + db;
ray.ra := ray.ra - dr-dblack;
ray.ga := ray.ga - dg-dblack;
ray.ba := ray.ba - db-dblack;
srBase.clamp3(ray.ra,ray.ga,ray.ba);
ray.a := (ray.ra+ray.ga+ray.ba)/3;
END Shade;
END RainbowVox;
TYPE JelloVox*=OBJECT(AlphaVox);
PROCEDURE Shade (VAR ray: Ray);
VAR
x,y,z: SREAL;
depth: SREAL;
dr, dg, db: SREAL;
BEGIN
depth := Math.sqrt(x*x+y*y+z*z);
dr := r*ray.ra*depth;
dg := g*ray.ga*depth;
db := b*ray.ba*depth;
ray.ra := ray.ra - dr;
ray.ga := ray.ga - dg;
ray.ba := ray.ba - db;
ray.a := (ray.ra+ray.ga+ray.ba)/3;
ray.length := ray.length + ray.scale;
END Shade;
END JelloVox;
TYPE AirVox*=OBJECT(ColoredVox);
PROCEDURE Shade (VAR ray: Ray);
VAR
x,y,z: SREAL;
depth: SREAL;
dr, dg, db: SREAL;
BEGIN
depth := Math.sqrt(x*x+y*y+z*z)*srBase.fog;
dr := r*ray.ra*depth;
dg := g*ray.ga*depth;
db := b*ray.ba*depth;
ray.ra := ray.ra - dr;
ray.ga := ray.ga - dg;
ray.ba := ray.ba - db;
ray.a := (ray.ra+ray.ga+ray.ba)/3;
ray.length := ray.length + ray.scale;
END Shade;
END AirVox;
TYPE InkVox*=OBJECT(ColoredVox);
PROCEDURE Shade (VAR ray: Ray);
VAR
ink: SREAL;
BEGIN
ink := 0.05*ray.a;
ray.ra := ray.ra - ink;
ray.ga := ray.ga - ink;
ray.ba := ray.ba - ink;
ray.a := (ray.ra+ray.ga+ray.ba)/3;
ray.length := ray.length + ray.scale;
END Shade;
END InkVox;
TYPE OutlineVox*=OBJECT(ColoredVox);
VAR
or, og, ob: SREAL;
PROCEDURE SetOutline* (red, green, blue: SREAL);
BEGIN
or := red ;
og := green ;
ob := blue;
END SetOutline;
PROCEDURE Shade (VAR ray: Ray);
VAR
ecount: INTEGER;
BEGIN
IF (ray.lxyz.x< 0.01) OR (ray.lxyz.x > 0.99) THEN INC(ecount) END;
IF (ray.lxyz.y <0.01) OR (ray.lxyz.y > 0.99) THEN INC(ecount) END;
IF (ray.lxyz.z < 0.01) OR (ray.lxyz.z > 0.99) THEN INC(ecount) END;
IF ecount > 1 THEN
ray.r := ray.r + or * ray.ra;
ray.g := ray.g + og * ray.ga;
ray.b := ray.b + ob * ray.ba;
ray.ra := 0;
ray.ga := 0;
ray.ba := 0;
ray.a := 0;
ELSE
ray.r := ray.r + r * ray.ra;
ray.g := ray.g + g * ray.ga;
ray.b := ray.b + b * ray.ba;
ray.ra := 0;
ray.ga := 0;
ray.ba := 0;
ray.a := 0;
END
END Shade;
END OutlineVox;
TYPE GoutlineVox*=OBJECT(ColoredVox)
VAR
tx, ty, tz: SREAL;
or, og, ob: SREAL;
PROCEDURE Shade (VAR ray: Ray);
VAR
ecount: INTEGER;
l, le, xe, ye, ze: SREAL;
BEGIN
ecount := 0;
IF (ray.lxyz.x < 1/100) THEN
xe := 100*(1/100-ray.lxyz.x)
ELSIF (ray.lxyz.x > 99/100) THEN
xe := 00*(1-ray.lxyz.x)
END;
IF (ray.lxyz.y < 1/100) THEN
ye := 100*(1/100-ray.lxyz.y)
ELSIF (ray.lxyz.y > 99/100) THEN
ye := 100*(1-ray.lxyz.y)
END;
IF (ray.lxyz.z < 1/100) THEN
ze := 100*(1/100-ray.lxyz.z)
ELSIF (ray.lxyz.z > 99/100) THEN
ze := 100*(1-ray.lxyz.z)
END;
le := (xe+ye+ze)/3;
l := (ray.lxyz.x+ray.lxyz.y+ray.lxyz.z)/3;
ray.r := ray.r + r * ray.ra*l;
ray.g := ray.g + g * ray.ga*l;
ray.b := ray.b + b * ray.ba*l;
ray.ra := 0;
ray.ga := 0;
ray.ba := 0;
ray.a := 0;
END Shade;
END GoutlineVox;
TYPE GouraudVox* = OBJECT(ColoredVox);
VAR
brightness: INTEGER;
PROCEDURE & init*;
BEGIN
brightness := 16;
END init;
PROCEDURE tick;
BEGIN
IF srBase.rand.Uniform()>1/2 THEN
brightness := (brightness + 1) MOD 20;
ELSE
brightness := (brightness - 1) MOD 20;
END
END tick;
PROCEDURE Shade (VAR ray: Ray);
VAR
l: SREAL;
BEGIN
l := (ray.lxyz.x+ray.lxyz.y+ray.lxyz.z)/3;
ray.r := ray.r + r * ray.ra*l;
ray.g := ray.g + g * ray.ga*l;
ray.b := ray.b + b * ray.ba*l;
ray.a := (ray.ra+ray.ga+ray.ba)/3;
END Shade;
END GouraudVox;
TYPE VGouraudVox* = OBJECT(GouraudVox);
PROCEDURE Shade (VAR ray: Ray);
VAR
l: SREAL;
BEGIN
l := (ray.lxyz.x+ray.lxyz.y)/2;
ray.r := ray.r + r * ray.ra*l;
ray.g := ray.g + g * ray.ga*l;
ray.b := ray.b + b * ray.ba*l;
ray.a := (ray.ra+ray.ga+ray.ba)/3;
END Shade;
END VGouraudVox;
TYPE HGouraudVox* = OBJECT(GouraudVox);
PROCEDURE Shade (VAR ray: Ray);
VAR
l: SREAL;
BEGIN
l := (ray.lxyz.x+ray.lxyz.z)/2;
ray.r := ray.r + r * ray.ra*l;
ray.g := ray.g + g * ray.ga*l;
ray.b := ray.b + b * ray.ba*l;
ray.ra := 0;
ray.ga := 0;
ray.ba := 0;
ray.a := 0;
END Shade;
END HGouraudVox;
TYPE NouraudVox* = OBJECT(ColoredVox);
PROCEDURE Shade (VAR ray: Ray);
VAR
l: SREAL;
BEGIN
l := 2*(ABS(1/2-ray.lxyz.x) + ABS(1/2-ray.lxyz.y) + ABS(1/2-ray.lxyz.z))/3;
ray.r := ray.r + r * ray.ra*l;
ray.g := ray.g + g * ray.ga*l;
ray.b := ray.b + b * ray.ba*l;
ray.ra := 0;
ray.ga := 0;
ray.ba := 0;
ray.a := 0;
END Shade;
END NouraudVox;
TYPE DiffuseVox* = OBJECT(ColoredVox);
PROCEDURE Shade (VAR ray: Ray);
VAR
nx, ny, nz: INTEGER;
dot: SREAL;
inside: BOOLEAN;
BEGIN
CASE ray.face OF
0: inside := TRUE
|1: nx := -1
|2: ny := -1
|3: nz := -1
|4: nx := 1
|5: ny := 1
|6: nz := 1
ELSE
END;
IF inside THEN dot := 1 ELSE dot := ABS(nx*ray.dxyz.x + ny*ray.dxyz.y+ nz*ray.dxyz.z) END;
IF dot<1/2 THEN dot:=1/2 END;
ray.r := ray.r + r * ray.ra*dot ;
ray.g := ray.g + g * ray.ga*dot;
ray.b := ray.b + b * ray.ba*dot;
ray.ra := 0;
ray.ga := 0;
ray.ba := 0;
ray.a := 0;
END Shade;
END DiffuseVox;
TYPE DiffuseNouraudVox* = OBJECT(ColoredVox);
PROCEDURE Shade (VAR ray: Ray);
VAR
nx, ny, nz: INTEGER;
dot: SREAL;
inside: BOOLEAN;
l: SREAL;
BEGIN
l := 2*(ABS(1/2-ray.lxyz.x) + ABS(1/2-ray.lxyz.y) + ABS(1/2-ray.lxyz.z))/3;
CASE ray.face OF
0: inside := TRUE
|1: nx := -1
|2: ny := -1
|3: nz := -1
|4: nx := 1
|5: ny := 1
|6: nz := 1
ELSE
END;
IF inside THEN dot := l ELSE dot := l*(1/3+2*ABS(nx*ray.dxyz.x + ny*ray.dxyz.y+ nz*ray.dxyz.z)/2) END;
ray.r := ray.r + r * ray.ra*dot;
ray.g := ray.g + g * ray.ga*dot;
ray.b := ray.b + b * ray.ba*dot;
ray.ra := 0;
ray.ga := 0;
ray.ba := 0;
ray.a := 0;
END Shade;
END DiffuseNouraudVox;
TYPE GridVox* = OBJECT(Voxel);
VAR
r, g, b, a, gr, gg, gb, ga, Z: SREAL;
PROCEDURE SetColor* (red, green, blue, alpha: SREAL);
BEGIN
r := red * alpha;
g := green * alpha;
b := blue * alpha;
a := alpha;
END SetColor;
PROCEDURE SetGridColor* (red, green, blue, alpha: SREAL);
BEGIN
gr := red * alpha;
gg := green * alpha;
gb := blue * alpha;
ga := alpha;
END SetGridColor;
PROCEDURE SetGrid*(z: SREAL);
BEGIN
Z := z;
END SetGrid;
PROCEDURE Shade (VAR ray: Ray);
VAR
lx, ly, x, y: SREAL;
i, j: LONGINT;
BEGIN
CASE ray.face OF
1: lx := ray.lxyz.y; ly := ray.lxyz.z;
|2: lx := ray.lxyz.x; ly := ray.lxyz.z;
|3: lx := ray.lxyz.x; ly := ray.lxyz.y;
|4: lx := ray.lxyz.y; ly := ray.lxyz.z;
|5: lx := ray.lxyz.x; ly := ray.lxyz.z;
|6: lx := ray.lxyz.x; ly := ray.lxyz.y;
ELSE
END;
x := lx*Z; y := ly*Z;
i := ENTIER(x); j := ENTIER(y);
x := x - i; y := y - j;
IF ((x<0.1) OR (y<0.1)) THEN
ray.r := ray.r + gr;
ray.g := ray.g + gg;
ray.b := ray.b + gb;
ray.ra := ray.ra - (gg+gb);
ray.ga := ray.ga - (gr+gb);
ray.ba := ray.ba - (gr+gg);
ELSE
ray.r := ray.r + r;
ray.g := ray.g + g;
ray.b := ray.b + b;
ray.ra := ray.ra - (g+b);
ray.ga := ray.ga - (r+b);
ray.ba := ray.ba - (r+g);
END;
ray.a := (ray.ra+ray.ga+ray.ba)/3;
END Shade;
END GridVox;
TYPE GridChirkleVox* = OBJECT(Voxel);
VAR
r, g, b, a, Z: SREAL;
PROCEDURE SetColor* (red, green, blue, alpha: SREAL);
BEGIN
r := red * alpha;
g := green * alpha;
b := blue * alpha;
a := alpha;
register;
END SetColor;
PROCEDURE Shade (VAR ray: Ray);
VAR
dx, dy, dz, d2: SREAL;
BEGIN
dx := (1/2-ray.lxyz.x);
dy := (1/2-ray.lxyz.y);
dz := (1/2-ray.lxyz.z);
d2 := dx*dx+dy+dy+dz+dz;
IF d2>1 THEN
ray.r := ray.r + r;
ray.g := ray.g + g;
ray.b := ray.b + b;
ray.ra := ray.ra - (g+b);
ray.ga := ray.ga - (r+b);
ray.ba := ray.ba - (r+g);
ray.a := (ray.ra+ray.ga+ray.ba)/3;
END
END Shade;
END GridChirkleVox;
TYPE CheckerVox* = OBJECT(Voxel);
VAR
r, g, b, a, Z: SREAL;
PROCEDURE SetColor* (red, green, blue, alpha: SREAL);
BEGIN
r := red * alpha;
g := green * alpha;
b := blue * alpha;
a := alpha;
register;
END SetColor;
PROCEDURE Shade (VAR ray: Ray);
VAR
d, x,y,z, dr, dg, db: SREAL;
ijk: srBase.IPT;
BEGIN
srE.E(ray.lxyz, ijk);
x := ray.lxyz.x*2- ijk.i*2;
y := ray.lxyz.y*2- ijk.j*2;
z := ray.lxyz.z*2- ijk.k*2;
d := ABS((1/2-x)*(1/2-x)*(1/2-z)*(Z));
dr := (1- ray.lxyz.x*d)*ray.ra;
dg := (1- ray.lxyz.y*d)*ray.ga;
db := (1 - ray.lxyz.z*d)*ray.ba;
ray.r := ray.r + dr;
ray.g := ray.g + dg;
ray.b := ray.b + db;
ray.ra := ray.ra - (dg+db);
ray.ga := ray.ga - (dr+db);
ray.ba := ray.ba - (dr+dg);
ray.a := (ray.ra+ray.ga+ray.ba)/3;
END Shade;
PROCEDURE tick*;
BEGIN
Z := 10+(srBase.frame MOD 13);
END tick;
END CheckerVox;
TYPE HexaVox* = OBJECT(Voxel);
VAR
V: Voxel;
hhx: SREAL;
PROCEDURE&init*;
BEGIN
hhx := 6;
END init;
PROCEDURE setVox*(v: Voxel);
BEGIN
V := v;
END setVox;
PROCEDURE connectmessage*;
BEGIN
Out.String("HexaVox"); Out.Ln;
END connectmessage;
PROCEDURE talk*(c: CHAR; VAR connection: BOOLEAN);
BEGIN
CASE c OF
'+': hhx := hhx + 0.05; Out.String("hhx +."); Out.Ln;
| 'G': hhx := hhx - 0.05; Out.String("hhx - "); Out.Ln;
ELSE
Out.String(".");
END;
END talk;
PROCEDURE Shade (VAR ray: Ray);
VAR
lx,ly: SREAL;
Q, gray: SREAL;
BEGIN
CASE ray.face OF
1: lx := ray.lxyz.y; ly := ray.lxyz.z;
|2: lx := ray.lxyz.x; ly := ray.lxyz.z;
|3: lx := ray.lxyz.x; ly := ray.lxyz.y;
|4: lx := ray.lxyz.y; ly := ray.lxyz.z;
|5: lx := ray.lxyz.x; ly := ray.lxyz.z;
|6: lx := ray.lxyz.x; ly := ray.lxyz.y;
ELSE
END;
Q := srHex.hexize2(50*0.866*lx, 50*0.866*ly);
IF Q < 1/10 THEN
gray := (1-Q*10);
ray.r := ray.r - gray*ray.ra;
ray.g := ray.g - gray*ray.ga;
ray.b := ray.b - gray*ray.ba;
ray.ra := ray.ra-gray;
ray.ga := ray.ga-gray;
ray.ba := ray.ba-gray;
ray.a := (ray.ra+ray.ga+ray.ba)/3;
END;
IF V # NIL THEN V.Shade(ray) END;
END Shade;
END HexaVox;
TYPE SPHexaVox*=OBJECT(HexaVox);
PROCEDURE ctop(x,y,z: SREAL; VAR th,ph: SREAL);
BEGIN
srBase.normalize(x,y,z);
th := 6.28*srMath.sin(x);
ph := 6.28*srMath.cos(y);
END ctop;
PROCEDURE Shade (VAR ray: Ray);
VAR
Q, gray: SREAL;
th,ph: SREAL;
BEGIN
ctop(ray.lxyz.x,ray.lxyz.y,ray.lxyz.z,th,ph);
Q := srHex.hexize2(3*0.866*th, 3*0.866*ph);
IF Q < 1/10 THEN
gray := (1-Q*10);
ray.ra := ray.ra - gray;
ray.ga := ray.ga - gray;
ray.ba := ray.ba - gray;
ray.a := (ray.ra+ray.ga+ray.ba)/3;
END;
IF V # NIL THEN V.Shade(ray) END;
END Shade;
END SPHexaVox;
TYPE PolkaVox* = OBJECT(Voxel);
VAR
brightness: INTEGER;
r, g, b, rr, gg, bb: SREAL;
PROCEDURE & init*;
BEGIN
brightness := 16;
END init;
PROCEDURE SetColor* (red, green, blue, r2, g2, b2 : SREAL);
BEGIN
r := srBase.clamp(red );
g := srBase.clamp(green );
b := srBase.clamp(blue );
rr := srBase.clamp(r2);
gg := srBase.clamp(g2);
bb := srBase.clamp(b2);
END SetColor;
PROCEDURE tick;
BEGIN
IF srBase.rand.Uniform()>1/2 THEN
brightness := (brightness + 1) MOD 20;
ELSE
brightness := (brightness - 1) MOD 20;
END
END tick;
PROCEDURE Shade (VAR ray: Ray);
VAR
l, x, y, z: SREAL;
nx, ny, nz: INTEGER;
dot: SREAL;
inside: BOOLEAN;
BEGIN
CASE ray.face OF
0: inside := TRUE
|1: nx := -1
|2: ny := -1
|3: nz := -1
|4: nx := 1
|5: ny := 1
|6: nz := 1
ELSE
END;
IF inside THEN dot := 1 ELSE dot := ABS(nx*ray.dxyz.x + ny*ray.dxyz.y+ nz*ray.dxyz.z) END; x := 2*ABS(1/2 - ray.lxyz.x);
y := 2*ABS(1/2 - ray.lxyz.y);
z := 2*ABS(1/2 - ray.lxyz.z);
l := (x+y+z)/3;
dot := dot*brightness;
ray.r := ray.r + (r * ray.ra*l)*dot + (rr * ray.ra*(1-l))*dot ;
ray.g := ray.g + g * ray.ga*l *dot+ (gg * ray.ga*(1-l))*dot;
ray.b := ray.b + b * ray.ba*l*dot + (bb * ray.ba*(1-l)*dot);
ray.ra := 0;
ray.ga := 0;
ray.ba := 0;
ray.a := 0;
END Shade;
END PolkaVox;
TYPE GeckoVox* = OBJECT(Voxel);
VAR
r, g, b, a: SREAL;
ecount: INTEGER;
PROCEDURE SetColor* (red, green, blue, alpha: SREAL);
BEGIN
r := red * alpha;
g := green * alpha;
b := blue * alpha;
a := alpha
END SetColor;
PROCEDURE Shade (VAR ray: Ray);
VAR
d, dr, dg, db: SREAL;
BEGIN
d := ABS((1/2-ray.lxyz.x)*(1/2-ray.lxyz.y)*(1/2-ray.lxyz.z)*70);
dr := r*ray.ra*d;
dg := g*ray.ga*d;
db := b*ray.ba*d;
ray.r := ray.r + dr;
ray.g := ray.g + dg;
ray.b := ray.b + db;
ray.ra := ray.ra - (dg+db);
ray.ga := ray.ga - (dr+db);
ray.ba := ray.ba - (dr+dg);
ray.a := (ray.ra+ray.ga+ray.ba)/3;
END Shade;
END GeckoVox;
TYPE BiVox* = OBJECT(Voxel);
VAR
v1, v2: Voxel;
PROCEDURE set*(x,y: Voxel);
BEGIN
v1 := x;
v2 := y;
END set;
PROCEDURE probe*(x,y,z: SREAL):Voxel;
VAR
v: Voxel;
BEGIN
v := v1.probe(x,y,z);
v := v2.probe(x,y,z);
RETURN(SELF);
END probe;
PROCEDURE Shade (VAR ray: Ray);
BEGIN
v1.Shade(ray);
v2.Shade(ray);
END Shade;
END BiVox;
TYPE FuzzyTVox*=OBJECT(AlphaVox);
VAR
fuzzdivisor, fuzzsubtract: SREAL;
PROCEDURE & init*;
BEGIN
passable := TRUE;
fuzzdivisor := 100;
fuzzsubtract := 0.005
END init;
PROCEDURE setFuzz*(f: SREAL);
BEGIN
fuzzdivisor := f;
fuzzsubtract := 1/(2*fuzzdivisor)
END setFuzz;
PROCEDURE Shade*(VAR ray: Ray);
VAR
dr, dg, db: SREAL;
BEGIN
ray.xyz.x := ray.xyz.x + srBase.rand.Uniform()/fuzzdivisor-fuzzsubtract;
ray.xyz.y := ray.xyz.y + srBase.rand.Uniform()/fuzzdivisor-fuzzsubtract;
ray.xyz.z:= ray.xyz.z + srBase.rand.Uniform()/fuzzdivisor-fuzzsubtract;
dr := r*ray.ra;
dg := g*ray.ga;
db := b*ray.ba;
ray.r := ray.r + dr;
ray.g := ray.g + dg;
ray.b := ray.b + db;
ray.ra := ray.ra - (dg+db);
ray.ga := ray.ga - (dr+db);
ray.ba := ray.ba - (dr+dg);
ray.a := (ray.ra+ray.ga+ray.ba)/3;
END Shade;
END FuzzyTVox;
PROCEDURE mirror(VAR ray: Ray);
BEGIN
CASE ray.face OF
1: ray.dxyz.x:= -ray.dxyz.x;
|2: ray.dxyz.y:= -ray.dxyz.y;
|3: ray.dxyz.z:= -ray.dxyz.z;
|4: ray.dxyz.x:= -ray.dxyz.x;
|5: ray.dxyz.y:= -ray.dxyz.y;
|6: ray.dxyz.z:= -ray.dxyz.z;
ELSE
END;
ray.changed := TRUE;
END mirror;
END srVoxel.