MODULE srTexVox;
IMPORT srBase, Raster, Graphics := WMGraphics, Random, Math, srMath;
TYPE SREAL=srBase.SREAL;
TYPE Ray = srBase.Ray;
TYPE Voxel = srBase.Voxel;
TYPE Name = srBase.Name;
TYPE TexVox* = OBJECT(Voxel);
VAR
img*: Raster.Image;
fmt: Raster.Format;
copy : Raster.Mode;
W,H, bpr,adr: LONGINT;
transparent*: BOOLEAN;
PROCEDURE & init*(n: Name);
BEGIN
Raster.InitMode(copy, Raster.srcCopy);
img :=Graphics.LoadImage(n, TRUE);
IF img#NIL THEN W := img.width-1; H:= img.height-1; END;
END init;
PROCEDURE Shade (VAR ray: Ray);
VAR
p: Raster.Pixel;
xi,yj: LONGINT;
X,Y: SREAL;
r,g,b: SREAL;
a, lx, ly: SREAL;
nx, ny, nz: INTEGER;
dot: SREAL;
inside: BOOLEAN;
BEGIN
IF img#NIL THEN
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 := ABS(nx*ray.dxyz.x + ny*ray.dxyz.y+ nz*ray.dxyz.z);
X:=(1-lx)*W; Y:=(1-ly)*H;
xi:=ENTIER(X)MOD W; yj:=H - (ENTIER(Y) MOD H);
Raster.Get(img,xi,yj,p,copy);
a:= ORD(p[3])/255; r := ORD(p[2])/255; g := ORD(p[1])/255; b := ORD(p[0])/255;
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 := ray.ra-(b+g);
ray.ga := ray.ga-(r+b);
ray.ba := ray.ba-(r+g);
srBase.clamp3(ray.ra,ray.ga, ray.ba);
ray.a := (ray.ra+ray.ga+ray.ba)/3;
END
END;
END Shade;
END TexVox;
TYPE texmirrorVox* = OBJECT(TexVox);
VAR
r, g, b, a, red, blue, green: SREAL;
PROCEDURE SetColor* (R, G, B, alpha: SREAL);
BEGIN
red := R; green := G; blue := B;
r := srBase.clamp(red * alpha);
g := srBase.clamp(green * alpha);
b := srBase.clamp(blue * alpha);
a := srBase.clamp(alpha);
END SetColor;
PROCEDURE Shade (VAR ray: Ray);
VAR
p: Raster.Pixel;
xi,yj: LONGINT;
X,Y: SREAL;
r,g,b: SREAL;
dr,dg,db: SREAL;
lx, ly: SREAL;
nx, ny, nz: INTEGER;
dot: SREAL;
inside: BOOLEAN;
BEGIN
IF img#NIL THEN
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 := ABS(nx*ray.dxyz.x + ny*ray.dxyz.y+ nz*ray.dxyz.z);
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:=(1-lx)*W; Y:=(1-ly)*H;
xi:=ENTIER(X) MOD W; yj:=ENTIER(Y) MOD H;
Raster.Get(img,xi,yj,p,copy);
r := ORD(p[2])/255; g := ORD(p[1])/255; b := ORD(p[0])/255;
dr := r*ray.ra*dot;
dg := g*ray.ga*dot;
db := b*ray.ba*dot;
ray.r := ray.r + dr;
ray.g := ray.g + dg;
ray.b := ray.b + db;
ray.ra := ray.ra - dr;
ray.ga := ray.ga - dg;
ray.ba := ray.ba- db;
ray.a := (ray.ra+ray.ga+ray.ba)/3;
IF ray.a > 0.25 THEN
mirror(ray)
ELSE
ray.a := 0
END
END
END;
END Shade;
END texmirrorVox;
TYPE scrollVox* = OBJECT(Voxel);
VAR
img*: Raster.Image;
fmt: Raster.Format;
copy : Raster.Mode;
w,h, bpr,adr: LONGINT;
transparent: BOOLEAN;
off: INTEGER;
PROCEDURE & init*(n: Name);
BEGIN
img :=Graphics.LoadImage(n, TRUE);
w := img.width-1; h := img.height-1;
Raster.InitMode(copy, Raster.srcCopy);
register;
END init;
PROCEDURE Shade (VAR ray: Ray);
VAR
p: Raster.Pixel;
x,y: LONGINT;
r,g,b: SREAL;
lx, ly: SREAL;
nx, ny, nz: INTEGER;
dot: SREAL;
inside: BOOLEAN;
BEGIN
IF img#NIL THEN
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 := ABS(nx*ray.dxyz.x + ny*ray.dxyz.y+ nz*ray.dxyz.z);
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 := ENTIER((1-lx)*w); y := ENTIER((1-ly)*h);
x := x MOD w;
y := y MOD h;
Raster.Get(img,(x+off) MOD w,(y+off) MOD h,p,copy);
r := ORD(p[2])/255; g := ORD(p[1])/255; b := ORD(p[0])/255;
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.a := 0;
END
END
END Shade;
END scrollVox;
TYPE interfereVox* = OBJECT(Voxel);
VAR
imgn, imgm*: Raster.Image;
fmt: Raster.Format;
copy : Raster.Mode;
w,h, bpr,adr: LONGINT;
done: BOOLEAN;
off: INTEGER;
PROCEDURE & init*(n,m: Name);
BEGIN
imgn:=Graphics.LoadImage(n, TRUE);
w := imgn.width-1; h := imgn.height-1;
imgm:=Graphics.LoadImage(n, TRUE);
w := imgm.width-1; h := imgm.height-1;
Raster.InitMode(copy, Raster.srcCopy);
register;
END init;
PROCEDURE Shade (VAR ray: Ray);
VAR
p: Raster.Pixel;
x,y: LONGINT;
r,g,b: SREAL;
lx, ly: 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; x := ENTIER((lx)*w); y := ENTIER((1-ly)*h);
IF x < 0 THEN x := 0 ELSIF x > w THEN x := w END;
IF y < 0 THEN y := 0 ELSIF y > h THEN y := h END;
Raster.Get(imgn,(x+off) MOD w,y,p,copy);
r := ORD(p[2])/255; g := ORD(p[1])/255; b := ORD(p[0])/255;
ray.r := ray.r + r ;
ray.g := ray.g + g ;
ray.b := ray.b + b ;
Raster.Get(imgm,x,y,p,copy);
r := ORD(p[0])/255; g := ORD(p[1])/255; b := ORD(p[0])/255;
ray.r := ray.r + r ;
ray.g := ray.g + g ;
ray.b := ray.b + b ;
ray.a := 0;
END Shade;
PROCEDURE tick;
BEGIN
off := SHORT((off+1) MOD w);
END tick;
END interfereVox;
TYPE TexSph*= OBJECT(TexVox);
VAR
cx, cy, cz: SREAL;
D2: SREAL;
PROCEDURE & init*(n: Name);
BEGIN
img :=Graphics.LoadImage(n, TRUE);
W := img.width-1; H:= img.height-1;
Raster.InitMode(copy, Raster.srcCopy);
D2 := 1/4;
cx := 1/2; cy := 1/2; cz := 1/2;
END init;
PROCEDURE ctop(x,y,z: SREAL; VAR th,ph,d: SREAL);
BEGIN
d := Math.sqrt((cx-x)*(cx-x) + (cy-y)*(cy-y) + (cz-z)*(cz-z));
th := 6.28*srMath.sin((x-cx)/d);
ph := 6.28*srMath.cos((y-cy)/d);
END ctop;
PROCEDURE Shade (VAR ray: Ray);
VAR
x,y,z, th,ph,r2, radius, r,g,b: SREAL;
ax, ay, az, bx, by, bz : SREAL;
i: INTEGER;
p: Raster.Pixel;
X,Y: LONGINT;
BEGIN
IF img#NIL THEN
ax := ray.lxyz.x; ay := ray.lxyz.y; az := ray.lxyz.z;
bx := ray.lxyz.x + ray.dxyz.x; by := ray.lxyz.y+ ray.dxyz.y; bz := ray.lxyz.z+ ray.dxyz.z;
x := (ax+bx)/2; y := (ay+by)/2; z := (az + bz)/2;
FOR i := 0 TO 12 DO
r2 := (cx-x)*(cx-x) + (cy-y)*(cy-y) + (cz-z)*(cz-z);
IF r2 < D2 THEN
bx := x; by := y; bz := z
ELSE
ax := x; ay := y; az := z
END;
x := (ax+bx)/2; y := (ay+by)/2; z := (az + bz)/2;
END;
IF (r2-D2) < 0.01 THEN
ctop(x,y,z, th, ph, radius);
X := (ENTIER(th * 100)) MOD W;
Y := (ENTIER(ph * 100)) MOD H;
Raster.Get(img, X, Y, p,copy);
r := ORD(p[2])/255; g := ORD(p[1])/255; b := ORD(p[0])/255;
ray.r := ray.r + r*ray.a;
ray.g := ray.g + g*ray.a;
ray.b := ray.b + b *ray.a;
ray.a := 0;
END
END;
END Shade;
END TexSph;
VAR
rand: Random.Generator;
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;
BEGIN
rand:=srBase.rand;
END srTexVox.