WindowWidth = DisplayWidth
WindowHeight = DisplayHeight
global winx , winy
gosub [math]
gosub [color]
gosub [ray]
p.y = -400
p.ny = 1
p.kl = green
stel = 0
call sphere -40,40,0 , 40 , red
call sphere 40,40,0 , 30 , yellow
ttel = 0
call tri 0,0,0 , 50,50,0 , 70,-50,0 , blue
call tri 0,0,0 , -30,30,0, -50,-30,0 , cyan
winx = WindowWidth
winy = WindowHeight
nomainwin
open "ray 2.0" for graphics as #m
#m "trapclose [quit]"
for x = -100 to 100
for y = -100 to 100
#m "goto ";winx/2+x;" ";winy/2+y
call setcolor render(0,0,-1000,x,y,1000,0)
#m "down"
#m "set ";winx/2+x;" ";winy/2+y
#m "up"
next y
next x
notice "ready"
wait
[quit]
close #m
end
''bluatigro 18 nov 2016
''math block
[math]
global pi , golden.ratio
pi = atn( 1 ) * 4
golden.ratio = ( sqr( 5 ) - 1 ) / 2
return
function rad( deg )
''from degrees to radians
rad = deg * pi / 180
end function
sub rotate byref k , byref l , deg
s = sin( rad( deg ) )
c = cos( rad( deg ) )
hk = k * c - l * s
hl = k * s + l * c
k = hk
l = hl
end sub
function nr$( no , m )
nr$ = right$( "00000000" ; no , m )
end function
sub saveframe f$ , no , m
#m "getbmp screen 0 0 " ; winx ; " " ; winy
bmpsave "screen" , f$ + nr$( no , m ) + ".bmp"
end sub
''bluatigro 18 nov 2016
''color block
''needs math block
[color]
global black , red , green , yellow
global blue , magenta , cyan , white
global pink , orange , gray , purple
black = rgb( 0 , 0 , 0 )
red = rgb( 255 , 0 , 0 )
green = rgb( 0 , 255 , 0 )
yellow = rgb( 255 , 255 , 0 )
blue = rgb( 0 , 0 , 255 )
magenta = rgb( 255 , 0 , 255 )
cyan = rgb( 0 , 255 , 255 )
white = rgb( 255 , 255 , 255 )
pink = rgb( 255 , 127 , 127 )
orange = rgb( 255 , 127 , 0 )
gray = rgb( 127 , 127 , 127 )
purple = rgb( 127 , 0 , 127 )
return
sub setcolor kl
r = int( kl and 255 )
g = int( kl / 256 ) and 255
b = int( kl / 256 / 256 ) and 255
print #m , "backcolor " ; r ;" "; g ; " "; b
print #m , "color " ; r ; " " ; g ; " " ; b
end sub
function rgb( r , g , b )
rgb = ( int( r ) and 255 ) _
+ ( int( g ) and 255 ) * 256 _
+ ( int( b ) and 255 ) * 256 * 256
end function
function rainbow( x )
r = sin( rad( x ) ) * 127 + 128
g = sin( rad( x - 120 ) ) * 127 + 128
b = sin( rad( x + 120 ) ) * 127 + 128
rainbow = rgb( r , g , b )
end function
function mix( kl1 , f , kl2 )
r1 = int( kl1 and 255 )
g1 = int( kl1 / 256 ) and 255
b1 = int( kl1 / 256 / 256 ) and 255
r2 = int( kl2 and 255 )
g2 = int( kl2 / 256 ) and 255
b2 = int( kl2 / 256 / 256 ) and 255
r = r1 + ( r2 - r1 ) * f
g = g1 + ( g2 - g1 ) * f
b = b1 + ( b2 - b1 ) * f
mix = rgb( r , g , b )
end function
''bluatigro 18 nov 2016
''ray casting block
''needs vector3D , color and math block
[ray]
global great , smal
great = 1e7
smal = 1e-7
global p.x,p.y,p.z,p.nx,p.ny,p.nz,p.kl
global smax , stel
smax = 10
dim s.x(smax),s.y(smax),s.z(smax),s.r(smax),s.r2(smax),s.kl(smax)
global tmax , ttel
tmax = 10
dim t.x0(tmax),t.y0(tmax),t.z0(tmax) _
,t.x1(tmax),t.y1(tmax),t.z1(tmax) _
,t.x2(tmax),t.y2(tmax),t.z2(tmax) _
,t.xn(tmax),t.yn(tmax),t.zn(tmax),t.kl(tmax)
return
function render(ox,oy,oz,dx,dy,dz,dept)
scan
p = plane.hit(0,ox,oy,oz,dx,dy,dz)
s = great
for i = 0 to stel
sdist = sphere.hit(i,ox,oy,oz,dx,dy,dz)
if sdist < s then
s = sdist
si = i
end if
next i
t = great
for i = 0 to ttel
tdist = tri.hit(i,ox,oy,oz,dx,dy,dz)
if tdist < t then
t = tdist
ti = i
end if
next i
if t < s and t < p then
uit = t.kl(ti)
else
if s < p then
call v.normalize x,y,z , dx,dy,dz
call v.add x,y,z , ox,oy,oz , x*s,y*s,z*s
call v.min x,y,z , x,y,z , s.x(si),s.y(si),s.z(si)
a = angle( x,y,z , 0,1,0 )
kl = mix( s.kl(si) , cos(a)/2+0.5 , black )
uit = kl
else
if p < great then
uit = p.kl
else
uit = black
end if
end if
end if
render = uit
end function
function plane.hit(no,ox,oy,oz,dx,dy,dz)
demon = dot(p.nx,p.ny,p.nz , dx,dy,dz)
if demon > smal then
call v.min x,y,z , p.x,p.y,p.z , ox,oy,oz
uit = dot(x,y,z , p.nx,p.ny,p.nz)
else
uit = great
end if
plane.hit = uit
end function
sub sphere x,y,z , d , kl
if stel > smax then exit sub
s.x(stel)=x
s.y(stel)=0-y
s.z(stel)=z
s.r(stel)=d
s.r2(stel)=d*d
s.kl(stel)=kl
stel=stel+1
end sub
function sphere.hit(no,ox,oy,oz,dx,dy,dz)
call v.min x,y,z , ox,oy,oz , s.x(no),s.y(no),s.z(no)
a = dot(dx,dy,dz , dx,dy,dz)
b = 2 * dot(x,y,z , dx,dy,dz)
c = dot(x,y,z , x,y,z)-s.r2(no)
disc = b*b-4*a*c
if disc < 0 then
uit = great
else
e = sqr(disc)
demon = 2*a
t = ( 0-b - e ) / demon
if t > smal then
uit = t
end if
t = ( 0-b + e ) / demon
if t > smal then
uit = t
end if
end if
sphere.hit = uit
end function
sub tri x0,y0,z0,x1,y1,z1,x2,y2,z2,kl
t.x0(ttel)=x0
t.y0(ttel)=y0
t.z0(ttel)=z0
t.x1(ttel)=x1
t.y1(ttel)=y1
t.z1(ttel)=z1
t.x2(ttel)=x2
t.y2(ttel)=y2
t.z2(ttel)=z2
t.kl(ttel)=kl
call v.min ax,ay,az , x2,y2,z2 , x0,y0,z0
call v.min bx,by,bz , x1,y1,z1 , x0,y0,z0
call v.cross xn,yn,zn , ax,ay,az , bx,by,bz
t.xn(ttel)=xn
t.yn(ttel)=yn
t.zn(ttel)=zn
ttel=ttel+1
end sub
function tri.hit(no,ox,oy,oz,dx,dy,dz)
call v.min e1x,e1y,e1z , t.x1(no),t.y1(no),t.z1(no) , t.x0(no),t.y0(no),t.z0(no)
call v.min e2x,e2y,e2z , t.x2(no),t.y2(no),t.z2(no) , t.x0(no),t.y0(no),t.z0(no)
call v.cross qx,qy,qz , dx,dy,dz , e2x,e2y,e2z
a = dot(e1x,e1y,e1z , qx,qy,qz)
if abs( a ) < smal then
tri.hit = great
exit function
end if
f = 1 / a
call v.min x,y,z , ox,oy,oz , t.x0,t.y0,t.z0
u = f*dot(x,y,z , qx,qy,qz)
if u < 0 or u > 1 then
tri.hit = great
exit function
end if
call v.cross x,y,z , x,y,z , e1x,e1y,e1z
v = f*dot(dx,dy,dz , x,y,z)
if v < 0 or u + v > 1 then
tri.hit = great
exit function
end if
tri.hit = f*dot(e2x,e2y,e2z , x,y,z)
end function
''bluatigro 18 nov 2016
''vector3D block
sub v.min byref x,byref y,byref z,a,b,c,d,e,f
x = a - d
y = b - e
z = c - f
end sub
sub v.add byref x,byref y,byref z,a,b,c,d,e,f
x = a + d
y = b + e
z = c + f
end sub
sub v.cross byref x,byref y,byrefz,x1,y1,z1,x2,y2,z2
x = y2*z1-z2*y1
y = z2*x1-x2*z1
z = x2*y1-y2*x1
end sub
sub v.normalize byref x,byref y,byref z,a,b,c
l = lenght(a,b,c)
x = a/l
y = b/l
z = c/l
end sub
function dot(a,b,c,d,e,f)
dot = a * d + b * e + c * f
end function
function angle(a,b,c,d,e,f)
dt = dot(a,b,c,d,e,f)
la = lenght(a,b,c)
lb = lenght(d,e,f)
angle = acs( dt / ( la * lb ) )
end function
function lenght(a,b,c)
lenght = sqr(a*a+b*b+c*c)
end function