LB Booster
General >> General Board >> ray casting 2.0
http://lbb.conforums.com/index.cgi?board=general&action=display&num=1479900371

ray casting 2.0
Post by bluatigro on Nov 23rd, 2016, 10:26am

error :
shading spheres ?
plane shoot be behynd

Code:
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