Liberty BASIC Community Forum
Special Topics and Projects >> Game and Graphic Programming >> ray casting 2.0
http://libertybasic.conforums.com/index.cgi?board=game&action=display&num=1479215275

ray casting 2.0
Post by bluatigro on Nov 15th, 2016, 07:07am


this is a 2e try at raycasting

error :
where is my red sphere

future :
triangle

Code:
WindowWidth = DisplayWidth
WindowHeight = DisplayHeight
global winx , winy , v.x , v.y , v.z , great , smal
great = 1e7
smal = 1e-7
global p.x,p.y,p.z,p.nx,p.ny,p.nz,p.kl
p.y = -400
p.ny = 1
p.kl = rgb(0,255,0)
global s.x,s.y,s.z,s.r,s.r2,s.kl
s.r = 30
s.r2 = s.r * s.r
s.kl = rgb(255,0,0)
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

''color math

function rgb(r,g,b)
  r = r and 255
  g = g and 255
  b = b and 255
  rgb = r+g*256+b*256^2
end function

function mix(kla,f,klb)
  ra = int( kla ) and 255
  ga = int( kla / 256 ) and 255
  ba = int( kla / 256 ^ 2 ) and 255  
  rb = int( klb ) and 255
  gb = int( klb / 256 ) and 255
  bb = int( klb / 256 ^ 2 ) and 255
  r = ra+(rb-ra)*f
  g = ga+(gb-ga)*f
  b = ba+(bb-ba)*f
  mix = rgb(r,g,b)
end function

sub setcolor kl
  r = int( kl ) and 255
  g = int( kl / 256 ) and 255
  b = int( kl / 256 ^ 2 ) and 255
  #m "color ";r;" ";g;" ";b
end sub

''ray math

function render(ox,oy,oz,dx,dy,dz,dept)
  scan
  p = plane.hit(0,ox,oy,oz,dx,dy,dz) 
  s = sphere.hit(0,ox,oy,oz,dx,dy,dz)
  if s < p then
    uit = s.kl
  else
    if p < great then
      uit = p.kl
    else
      uit = 0
    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 p.x,p.y,p.z,ox,oy,oz
    uit = dot(v.x,v.y,v.z,p.nx,p.ny,p.nz)
  else
    uit = great
  end if
  plane.hit = uit
end function

function sphere.hit(no,ox,oy,oz,dx,dy,dz)
  call v.min ox,oy,oz , s.x,s.y,s.z
  a = dot(dx,dy,dz,dx,dy,dz)
  b = 2 - dot(v.x,v.y,v.z,dx,dy,dz )
  c = dot(v.x,v.y,v.z,v.x,v.y,v.z)-s.r2
  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

''vector 3d math

sub v.min a,b,c,d,e,f
  v.x = a - d
  v.y = b - e
  v.z = c - f
end sub

sub v.add a,b,c,d,e,f
  v.x = a + d
  v.y = b + e
  v.z = c + f
end sub

sub v.normalize a,b,c
  l = lenght(a,b,c)
  v.x = a/l
  v.y = b/l
  v.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
 

Re: ray casting 2.0
Post by bluatigro on Nov 15th, 2016, 08:04am

update :
blue triangle added

error :
wehere are my red sphere amd blue triangle
Code:
WindowWidth = DisplayWidth
WindowHeight = DisplayHeight
global winx , winy , v.x , v.y , v.z , great , smal
great = 1e7
smal = 1e-7
global p.x,p.y,p.z,p.nx,p.ny,p.nz,p.kl
p.y = -400
p.ny = 1
p.kl = rgb(0,255,0)
global s.x,s.y,s.z,s.r,s.r2,s.kl
s.r = 30
s.r2 = s.r * s.r
s.kl = rgb(255,0,0)
global t.x0,t.y0,t.z0,t.x1,t.y1,t.z1,t.x2.t.y2,t.z2,t.kl
t.x1 = 100
t.y1 = 50
t.x2 = 100
t.y2 = -50
t.kl = rgb(0,0,255)
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

''color math

function rgb(r,g,b)
  r = r and 255
  g = g and 255
  b = b and 255
  rgb = r+g*256+b*256^2
end function

function mix(kla,f,klb)
  ra = int( kla ) and 255
  ga = int( kla / 256 ) and 255
  ba = int( kla / 256 ^ 2 ) and 255  
  rb = int( klb ) and 255
  gb = int( klb / 256 ) and 255
  bb = int( klb / 256 ^ 2 ) and 255
  r = ra+(rb-ra)*f
  g = ga+(gb-ga)*f
  b = ba+(bb-ba)*f
  mix = rgb(r,g,b)
end function

sub setcolor kl
  r = int( kl ) and 255
  g = int( kl / 256 ) and 255
  b = int( kl / 256 ^ 2 ) and 255
  #m "color ";r;" ";g;" ";b
end sub

''ray math

function render(ox,oy,oz,dx,dy,dz,dept)
  scan
  p = plane.hit(0,ox,oy,oz,dx,dy,dz) 
  s = sphere.hit(0,ox,oy,oz,dx,dy,dz)
  t = tri.hit(0,ox,oy,oz,dx,dy,dz)
  if t < s and t < p then
    uit = t.kl
  else
    if s < p then
      uit = s.kl
    else
      if p < great then
        uit = p.kl
      else
        uit = 0
      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 p.x,p.y,p.z,ox,oy,oz
    uit = dot(v.x,v.y,v.z,p.nx,p.ny,p.nz)
  else
    uit = great
  end if
  plane.hit = uit
end function

function sphere.hit(no,ox,oy,oz,dx,dy,dz)
  call v.min ox,oy,oz , s.x,s.y,s.z
  a = dot(dx,dy,dz,dx,dy,dz)
  b = 2 - dot(v.x,v.y,v.z,dx,dy,dz )
  c = dot(v.x,v.y,v.z,v.x,v.y,v.z)-s.r2
  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

function tri.hit(no,ox,oy,oz,dx,dy,dz)
  call v.min t.x1,t.y1,t.z1 , t.x0,t.y0,t.z0
  e1x = v.x : e1y = v.y : e1z = v.z
  call v.min t.x2,t.y2,t.z2 , t.x0,t.y0,t.z0
  e2x = v.x : e2y = v.y : e2z = v.z
  call v.cross dx,dy,dz , e2x,e2y,e2z
  qx = v.x : qy = v.y : qz = v.z
  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 ox,oy,oz,t.x0,t.y0,t.z0
  u = f*dot(v.x,v.y,v.z,qx,qy,qz)
  if u < 0 or u > 1 then 
    tri.hit = great
    exit function
  end if
  call v.cross v.x,v.y,v.z,e1x,e1y,e1z
  v = f*dot(dx,dy,dz,v.x,v.y,v.z)
  if v < 0 or u + v > 1 then
    tri.hit = great
    exit function
  end if
  tri.hit = f*dot(e2x,e2y,e2z,v.x,v.y,v.z)
end function

''vector 3d math

sub v.min a,b,c,d,e,f
  v.x = a - d
  v.y = b - e
  v.z = c - f
end sub

sub v.add a,b,c,d,e,f
  v.x = a + d
  v.y = b + e
  v.z = c + f
end sub

sub v.cross x1,y1,z1,x2,y2,z2
  v.x = y2*z1-z2*y1
  v.y = z2*x1-x2*z1
  v.z = x2*y1-y2*x1
end sub

sub v.normalize a,b,c
  l = lenght(a,b,c)
  v.x = a/l
  v.y = b/l
  v.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
 

Re: ray casting 2.0
Post by bluatigro on Nov 18th, 2016, 06:55am

update :
i reogenized my code into blocks
eatch block has its own file
that way i dont need to code things 2x

error :
i got no red sphere but a red sky
blue triangle not visable

Code:
WindowWidth = DisplayWidth
WindowHeight = DisplayHeight
global winx , winy
gosub [math]
gosub [color]
gosub [vector3D]
gosub [ray]
p.y = -400
p.ny = 1
p.kl = green
s.r = 30
s.r2 = s.r * s.r
s.kl = red
t.x1 = 100
t.y1 = 50
t.x2 = 100
t.y2 = -50
t.kl = blue
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 s.x,s.y,s.z,s.r,s.r2,s.kl
  global t.x0,t.y0,t.z0,t.x1,t.y1,t.z1,t.x2.t.y2,t.z2,t.kl
return

function render(ox,oy,oz,dx,dy,dz,dept)
  scan
  p = plane.hit(0,ox,oy,oz,dx,dy,dz)
  s = sphere.hit(0,ox,oy,oz,dx,dy,dz)
  t = tri.hit(0,ox,oy,oz,dx,dy,dz)
  if t < s and t < p then
    uit = t.kl
  else
    if s < p then
      uit = s.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 p.x,p.y,p.z,ox,oy,oz
    uit = dot(v.x,v.y,v.z,p.nx,p.ny,p.nz)
  else
    uit = great
  end if
  plane.hit = uit
end function

function sphere.hit(no,ox,oy,oz,dx,dy,dz)
  call v.min ox,oy,oz , s.x,s.y,s.z
  a = dot(dx,dy,dz,dx,dy,dz)
  b = 2 * dot(v.x,v.y,v.z,dx,dy,dz )
  c = dot(v.x,v.y,v.z,v.x,v.y,v.z)-s.r2
  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

function tri.hit(no,ox,oy,oz,dx,dy,dz)
  call v.min t.x1,t.y1,t.z1 , t.x0,t.y0,t.z0
  e1x = v.x : e1y = v.y : e1z = v.z
  call v.min t.x2,t.y2,t.z2 , t.x0,t.y0,t.z0
  e2x = v.x : e2y = v.y : e2z = v.z
  call v.cross dx,dy,dz , e2x,e2y,e2z
  qx = v.x : qy = v.y : qz = v.z
  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 ox,oy,oz,t.x0,t.y0,t.z0
  u = f*dot(v.x,v.y,v.z,qx,qy,qz)
  if u < 0 or u > 1 then
    tri.hit = great
    exit function
  end if
  call v.cross v.x,v.y,v.z,e1x,e1y,e1z
  v = f*dot(dx,dy,dz,v.x,v.y,v.z)
  if v < 0 or u + v > 1 then
    tri.hit = great
    exit function
  end if
  tri.hit = f*dot(e2x,e2y,e2z,v.x,v.y,v.z)
end function

''bluatigro 18 nov 2016
''vector3D block

[vector3D]
  global v.x , v.y , v.z
return

sub v.min a,b,c,d,e,f
  v.x = a - d
  v.y = b - e
  v.z = c - f
end sub

sub v.add a,b,c,d,e,f
  v.x = a + d
  v.y = b + e
  v.z = c + f
end sub

sub v.cross x1,y1,z1,x2,y2,z2
  v.x = y2*z1-z2*y1
  v.y = z2*x1-x2*z1
  v.z = x2*y1-y2*x1
end sub

sub v.normalize a,b,c
  l = lenght(a,b,c)
  v.x = a/l
  v.y = b/l
  v.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

 

Re: ray casting 2.0
Post by bluatigro on Nov 21st, 2016, 06:39am

update :
more spheres

error :
sphere 0 not visable

triangle works !!

Code:
WindowWidth = DisplayWidth
WindowHeight = DisplayHeight
global winx , winy
gosub [math]
gosub [color]
gosub [vector3D]
gosub [ray]
p.y = -400
p.ny = 1
p.kl = green
stel = 0
call sphere 0,0,0 , 40 , pink
t.x1 = 50
t.y1 = 50
t.x2 = 70
t.y2 = -50
t.kl = blue
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 t.x0,t.y0,t.z0,t.x1,t.y1,t.z1,t.x2,t.y2,t.z2,t.kl
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 = tri.hit(0,ox,oy,oz,dx,dy,dz)
  if t < s and t < p then
    uit = t.kl
  else
    if s < p then
      call v.normalize dx,dy,dz
      call v.add ox,oy,oz,v.x*s,v.y*s,v.z*s
      call v.min v.x,v.y,v.z,s.x(si),s.y(si),s.z(si)
      a = angle( v.x,v.y,v.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 p.x,p.y,p.z,ox,oy,oz
    uit = dot(v.x,v.y,v.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)=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 ox,oy,oz , s.x(no),s.y(no),s.z(no)
  a = dot(dx,dy,dz,dx,dy,dz)
  b = 2 * dot(v.x,v.y,v.z,dx,dy,dz )
  c = dot(v.x,v.y,v.z,v.x,v.y,v.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

function tri.hit(no,ox,oy,oz,dx,dy,dz)
  call v.min t.x1,t.y1,t.z1 , t.x0,t.y0,t.z0
  e1x = v.x : e1y = v.y : e1z = v.z
  call v.min t.x2,t.y2,t.z2 , t.x0,t.y0,t.z0
  e2x = v.x : e2y = v.y : e2z = v.z
  call v.cross dx,dy,dz , e2x,e2y,e2z
  qx = v.x : qy = v.y : qz = v.z
  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 ox,oy,oz,t.x0,t.y0,t.z0
  u = f*dot(v.x,v.y,v.z,qx,qy,qz)
  if u < 0 or u > 1 then
    tri.hit = great
    exit function
  end if
  call v.cross v.x,v.y,v.z,e1x,e1y,e1z
  v = f*dot(dx,dy,dz,v.x,v.y,v.z)
  if v < 0 or u + v > 1 then
    tri.hit = great
    exit function
  end if
  tri.hit = f*dot(e2x,e2y,e2z,v.x,v.y,v.z)
end function

''bluatigro 18 nov 2016
''vector3D block

[vector3D]
  global v.x , v.y , v.z
return

sub v.min a,b,c,d,e,f
  v.x = a - d
  v.y = b - e
  v.z = c - f
end sub

sub v.add a,b,c,d,e,f
  v.x = a + d
  v.y = b + e
  v.z = c + f
end sub

sub v.cross x1,y1,z1,x2,y2,z2
  v.x = y2*z1-z2*y1
  v.y = z2*x1-x2*z1
  v.z = x2*y1-y2*x1
end sub

sub v.normalize a,b,c
  l = lenght(a,b,c)
  v.x = a/l
  v.y = b/l
  v.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
 

Re: ray casting 2.0
Post by bluatigro on Nov 23rd, 2016, 04:38am

update :
new vector3D math

spheres visable

error :
shading not working

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
t.x1 = 50
t.y1 = 50
t.x2 = 70
t.y2 = -50
t.kl = blue
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 t.x0,t.y0,t.z0,t.x1,t.y1,t.z1,t.x2,t.y2,t.z2,t.kl
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 = tri.hit(0,ox,oy,oz,dx,dy,dz)
  if t < s and t < p then
    uit = t.kl
  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

function tri.hit(no,ox,oy,oz,dx,dy,dz)
  call v.min e1x,e1y,e1z , t.x1,t.y1,t.z1 , t.x0,t.y0,t.z0
  call v.min e2x,e2y,e2z , t.x2,t.y2,t.z2 , t.x0,t.y0,t.z0
  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

 

Re: ray casting 2.0
Post by bluatigro on Nov 23rd, 2016, 05:21am

update :
more triangles

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

 

Re: ray casting 2.0
Post by Rod on Nov 23rd, 2016, 06:17am

Your angle value never seems to change so the sphere is monotone.
Re: ray casting 2.0
Post by bluatigro on Nov 23rd, 2016, 07:44am

@ rod :
that shoot not be

i added some REM to show wat it shoot do
where do i go wrong ?

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 0,0,0 , 80 , 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)
  p = great
  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
      ''d = d - cam
      call v.min dx,dy,dz , dx,dy,dz , ox,oy,oz
      ''d.normalize
      call v.normalize dx,dy,dz , dx,dy,dz
      ''q = o + d * s
      call v.add qx,qy,qz , ox,oy,oz , dx*s,dy*s,dz*s
      ''normal = q - s.center
      call v.min x,y,z , qx,qy,qz , s.x(si),s.y(si),s.z(si)
      ''a = angle( normal , light )
      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

 

Re: ray casting 2.0
Post by Rod on Nov 23rd, 2016, 12:32pm

To remind every one, debugging your own code is the most fun you can have with Liberty BASIC.

Bluatigro needs some help because he can't see just as well as us.

Blautigro's code is criptic because he reads a letter at a time and can't do verbose variable names.

Hope he is not offended by this disclosure but he tackles some mighty complex code so the more time you can spend on it the better we all are off.

3D will never be Liberty BASIC's forte but the education is worth while.
ray casting 3.0
Post by bluatigro on Dec 1st, 2016, 06:37am

update :
i posted the code in [blocks] [see below]
so that you can construct the hole program

this is a example why i need include

the code draws verry slow it takes minutes

Code:
WindowWidth = DisplayWidth
WindowHeight = DisplayHeight
global winx , winy
winx = WindowWidth
winy = WindowHeight
gosub [math]
gosub [color]
gosub [ray]
gosub [basis3D]
gosub [avartar]
nomainwin
open "ray 3.0" for graphics as #m
  #m "trapclose [qiut]"
  call camara 0,0,0 , 0,0,0 , 1
  call link 1 , -100,100,0 , 30,0,0 , 0 , 0
  call man yellow , blue
  call link 1 , 100,100,0 , 30,0,0 , 0 , 0
  call pilko orange

  for x = 0-winx/2 to winx/2
    for y = 0-winy/2 to winy/2
      kl = render(0,0,-1000 , x,y,1000 , 0)
      call setcolor kl
      #m "goto ";winx/2+x;" ";winy/2+y
      #m "down"
      #m "set ";winx/2+x;" ";winy/2+y
      #m "up"
    next y
  next x
  call saveframe "ray" , 0 , 2
  notice "ready"
wait
[quit]
  close #m
end
''add [blocks] :
''math
''color
''ray world
''basis3D
''vector3D
''avartar
''animation
 

[blocks] code at :
http://libertybasic.nl/viewtopic.php?f=4&t=698
Re: ray casting 2.0
Post by bluatigro on Dec 14th, 2016, 04:41am

update :
removed plane
using big sphere as plane

error :
my sky is part plane

Code:
WindowWidth = DisplayWidth
WindowHeight = DisplayHeight
global winx , winy
gosub [math]
gosub [color]
gosub [ray]
stel = 0
call sphere 0,-1e7-100,0 , 1e7 , green
call sphere 0,0,0 , 80 , 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 , false , true
  pi = atn( 1 ) * 4
  golden.ratio = ( sqr( 5 ) - 1 ) / 2
  false = 0
  true = not( false )
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

''bluatigro 15 dec 2016
''animation block

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 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 = great
  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
  uit = black
  if t < great or s < great then
    if t < s then
      uit = t.kl(ti)
    else
      ''d = d - cam
      call v.min dx,dy,dz , dx,dy,dz , ox,oy,oz
      ''d.normalize
      call v.normalize dx,dy,dz , dx,dy,dz
      ''q = o + d * s
      call v.add qx,qy,qz , ox,oy,oz , dx*s,dy*s,dz*s
      ''normal = q - s.center
      call v.min x,y,z , qx,qy,qz , s.x(si),s.y(si),s.z(si)
      ''a = angle( normal , light )
      a = v.angle( x,y,z , 0,1,0 )
      kl = mix( s.kl(si) , cos(a)/2+0.5 , black )
      uit = kl
    end if
  end if
  render = 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 = v.dot(dx,dy,dz , dx,dy,dz)
  b = 2 * v.dot(x,y,z , dx,dy,dz)
  c = v.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 = v.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*v.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*v.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*v.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 = v.lenght(a,b,c)
  x = a/l
  y = b/l
  z = c/l
end sub

function v.dot(a,b,c,d,e,f)
  v.dot = a * d + b * e + c * f
end function

function v.angle(a,b,c,d,e,f)
  dt = v.dot(a,b,c,d,e,f)
  la = v.lenght(a,b,c)
  lb = v.lenght(d,e,f)
  v.angle = acs( dt / ( la * lb ) )
end function

function v.lenght(a,b,c)
  v.lenght = sqr(a*a+b*b+c*c)
end function

 

Re: ray casting 2.0
Post by bluatigro on Jun 22nd, 2017, 04:33am

update :
the material of the spheres and triangles
have now a :
diffuse
ambient
specular
emision
shininess
reflection
part

how do i calc the final color whit these ?

error :
i got a plane sphere
and my ground is also sky

Code:
WindowWidth = DisplayWidth
WindowHeight = DisplayHeight
global winx , winy
gosub [math]
gosub [color]
gosub [ray]
stel = 0
call setmat green , black , black , black , 0 , 0.5
call sphere 0,-100 - great ,0 , great
call setmat yellow , black , black , black , 0 , 0.5
call sphere 0,0,0 , 80
ttel = 0
''call tri 0,0,0 , 50,50,0 , 70,-50,0
''call tri 0,0,0 , -30,30,0, -50,-30,0
winx = WindowWidth
winy = WindowHeight
nomainwin
open "ray 3.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,2)
      #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 22 jun 2017
''ray casting block
''needs vector3D , color and math block

[ray]
  global great , smal
  great = 1e9
  smal = 1e-9
  global smax , stel
  global m.diffuse,m.ambient,m.refect
  global m.specular,m.emision,m.shininess
  smax = 10
  dim s.x(smax),s.y(smax),s.z(smax),s.r(smax),s.r2(smax)
  dim s.diffuse(smax),s.ambient(smax),s.reflect(smax)
  dim s.specular(smax),s.emision(smax),s.shininess(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)
  dim t.diffuse(tmax),t.ambient(tmax),t.reflect(tmax)
  dim t.specular(tmax),t.emision(tmax),t.shininess(tmax)
return

function render(ox,oy,oz,dx,dy,dz,dept)
  scan
  s = great
  si = -1
  for i = 0 to stel - 1
    sdist = sphere.hit(i,ox,oy,oz,dx,dy,dz)
    if sdist < s then
      s = sdist
      si = i
    end if
  next i
  t = great
  ti = -1
  for i = 0 to ttel - 1
    tdist = tri.hit(i,ox,oy,oz,dx,dy,dz)
    if tdist < t then
      t = tdist
      ti = i
    end if
  next i
  if si >= 0 or ti >= 0 then
    if t < s then
      nx = t.xn(ti)
      ny = t.yn(ti)
      nz = t.zn(ti)
      ''d = d - cam
      call v.min dx,dy,dz , dx,dy,dz , ox,oy,oz
      ''d.normalize
      call v.normalize dx,dy,dz , dx,dy,dz
      ''q = cam + d * s
      call v.add qx,qy,qz , ox,oy,oz , dx*t,dy*t,dz*t
      diffuse = t.diffuse(ti)
      ambient = t.ambient(ti)
      reflect = t.reflect(ti)
      specular = t.specular(ti)
      emision = t.emision(ti)
      shininess = t.shininess(ti)
    else
      ''d.normalize
      call v.normalize dx,dy,dz , dx,dy,dz
      ''q = cam + d * s
      call v.add qx,qy,qz , ox,oy,oz , dx*s,dy*s,dz*s
      ''normal = q - s.center
      call v.min nx,ny,nz , qx,qy,qz , s.x(si),s.y(si),s.z(si)
      diffuse = s.diffuse(si)
      ambient = s.ambient(si)
      reflect = s.reflect(si)
      specular = s.specular(si)
      emision = s.emision(si)
      shininess = s.shininess(si)
    end if
    a = angle( nx,ny,nz , 0,1,0 )
    uit = mix( diffuse , cos( a ) / 2 + .5 , black )
    if reflect > 0.001 and dept > 0 then
      call v.mirror dx,dy,dz , nx,ny,nz
      q = render( qx,qy,qz , dx,dy,dz , dept - 1 )
      uit = mix( uit , reflect , q )
    end if
  else
    uit = black
  end if
  render = uit
end function

sub setmat diff,amb,sp,em,shi,r
  m.diffuse = diff
  m.ambient = amb
  m.specular = sp
  m.emision = em
  m.shininess = shi
  m.reflect = r
end sub

sub sphere x,y,z , d
  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.diffuse(stel)=m.diffuse
  s.amient(stel)=m.ambient
  s.specular(stel)=m.specular
  s.emision(stel)=m.emision
  s.shininess(stel)=m.shininess
  s.reflect(stel)=m.reflect
  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
  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.diffuse(ttel)=kl
  t.reflect(ttel)=r
  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
  t.diffuse(ttel)=m.diffuse
  t.amient(ttel)=m.ambient
  t.specular(ttel)=m.specular
  t.emision(ttel)=m.emision
  t.shininess(ttel)=m.shininess
  t.reflect(ttel)=m.reflect
  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(no),t.y0(no),t.z0(no)
  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

sub v.mirror byref d.x,byref d.y,byref d.z , n.x,n.y,n.z
  if nz = 0 then exit sub
  xz = atn( n.x / n.z )
  call rotate n.x , n.z , 0-xz
  call rotate d.x , d.z , 0-xz
  yz = atn( n.y / n.z )
  call rotate d.y , d.z , 0-yz
  d.z = d.z * -1
  call rotate d.y , d.z , yz
  call rotate d.x , d.z , xz
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

 

Re: ray casting 2.0
Post by bluatigro on Jan 5th, 2018, 08:07am

i restarted from scratch

error :
sph() array out of bounds -1000

Code:
global t.x,t.y,t.z,t.d,t.d2,t.diffuse,t.reflect
global sphtel,sphmax,infinity
sphmax=100
infinity=1e9
dim sph(sphmax,10)
t.x=0
t.y=1
t.z=2
t.d=3
t.d2=4
t.reflect=5
t.diffuse=6
WindowWidth=DisplayWidth
WindowHeight=DisplayHeight
global winx,winy
winx=WindowWidth
winy=WindowHeight
red=rgb(255,0,0)
nomainwin
open "raytracer 1.0" for graphics as #m
  #m "trapclose [quit]"
  sphtel=0
  call sphere 0,0,0 , 50 , red , 0
  o.x=0
  o.y=0
  o.z=-1000
  for x=-100 to 100
    for y=-100 to 100
      d.x=x
      d.y=y
      d.z=1000
      kl=render( o.x,o.y,o.z , d.x,d.y,d.z , 7 )
      call setpixel x+winx/2,y+winy/2,kl
    next y
  next x
wait
[quit]
  close #m
end

function render( o.x,o.y,o.z , d.x,d.y,d.z , dept )
  scan
  low = infinity
  isph = -1
  for i = 0 to sphtel
    dist = hit(i , o.x,o.y,o.z , d.x,d.y,d.z )
    if dist < low then
      low = dist
      isph = i
    end if
  next i
  if isph = -1 then exit function
  call maal d.x,d.y,d.z , d.x,d.y,d.z , low
  call plus p.x,p.y,p.z , o.x,o.y,o.z , d.x,d.y,d.z
  c.x=sph(isph,t.x)
  c.y=sph(isph,t.y)
  c.z=sph(isph,t.z)
  call minus n.x,n.y,n.z , p.x,p.y,p.z , c.x,c.y,c.z
  angle=getangle( n.x,n.y,n.z , -1,1,-1 )
  kl=sph(isph,t.diffuse)
  render=mix(kl,cos(angle)/2+.5,0)
end function
function rgb(r,g,b)
  r=r and 255
  g=g and 255
  b=b and 255
  rgb=r+g*256+b*256^2
end function
sub setpixel x , y , kl
  r=int(kl)and 255
  g=int(kl/256)and 255
  b=int(kl/256^2)and 255
  #m "color ";r;" ";g;" ";b
  #m "goto ";x;" ";y
  #m "down"
  #m "set ";x;" ";y
  #m "up"
end sub
function mix(kl1,f,kl2)
  r1=int(kl1)and 255
  g1=int(kl1/256)and 255
  b1=int(kl1/256^2)and 255
  r2=int(kl2)and 255
  g2=int(kl2/256)and 255
  b2=int(kl2/256^2)and 255
  r=r1+(r2-r1)*f
  g=g1+(g2-g1)*f
  b=b1+(b2-b1)*f
  mix=rgb(r,g,b)
end function
sub minus byref a,byref b,byref c , x1,y1,z1 , x2,y2,z2
  a=x1-x2
  b=y1-y2
  c=z1-z2
end sub
sub plus byref a,byref b,byref c , x1,y1,z1 , x2,y2,z2
  a=x1+x2
  b=y1+y2
  c=z1+z2
end sub
sub maal byref a,byref b,byref c , x1,y1,z1 , q
  a=x1*q
  b=y1*q
  c=z1*q
end sub
sub div byref a,byref b,byref c , x1,y1,z1 , q
  a=x1/q
  b=y1/q
  c=z1/q
end sub
function getangle( a.x,a.y,a.z , b.x,b.y,b.z )
  la=lenght( a.x,a.y,a.z )
  lb=lenght( b.x,b.y,b.z )
  d=dot( a.x,a.y,a.z , b.x,b.y,b.z )
  getangle = acs(d/(la*lb))
end function
function lenght( a,b,c )
  lenght=sqr(dot(a,b,c,a,b,c))
end function
function dot( x1,y1,z1 , z2,y2,z2 )
  dot=x1*x2+y1*y2+z1*z2
end function
sub sphere x,y,z , d , kl,r
  sph(sphtel,t.x)=x
  sph(sphtel,t.y)=y
  sph(sphtel,t.z)=z
  sph(sphtel,t.d)=d
  sph(sphtel,t.d2)=d*d
  sph(sphtel,t.diffuse)=kl
  sph(sphtel,t.reflect)=r
  sphtel=sphtel+1
end sub
function hit( no , o.x,o.y,o.z , d.x,d.y,d.z )
  c.x=sph(no,t.x)
  c.y=sph(no,t.y)
  c.z=sph(no,t.z)
  call minus t.x,t.y,t.z , o.x,o.y,o.z , c.x,c.y,c.z
  a = dot( d.x,d.y,d.z , d.x,d.y,d.z )
  b = 2 * dot( t.x,t.y,t.z , d.x,d.y,d.z )
  c = dot( t.x,t.y,t.z , t.x,t.y,t.z ) - sph(no,t.d2)
  disc = b ^ 2 - 4 * a * c
  if disc < 0 then
    hit = inifity
    exit function
  else
    e = sqr( disc )
    demon = 2 * a
    t = ( 0-b - e ) / demon
    if t > 1e-12 then
      hit = t
      exit function
    end if

    t = ( 0-b + e ) / demon
    if t > 1e-12 then
      hit = t
      exit function
    end if
  end if
  hit = infinity
end function

 

Re: ray casting 2.0
Post by bluatigro on Jan 5th, 2018, 08:14am

stupid error of me
used t.* 2 x

error :
iligal float calc

Code:
global t.x,t.y,t.z,t.d,t.d2,t.diffuse,t.reflect
global sphtel,sphmax,infinity
sphmax=100
infinity=1e9
dim sph(sphmax,10)
t.x=0
t.y=1
t.z=2
t.d=3
t.d2=4
t.reflect=5
t.diffuse=6
WindowWidth=DisplayWidth
WindowHeight=DisplayHeight
global winx,winy
winx=WindowWidth
winy=WindowHeight
red=rgb(255,0,0)
nomainwin
open "raytracer 1.0" for graphics as #m
  #m "trapclose [quit]"
  sphtel=0
  call sphere 0,0,0 , 50 , red , 0
  o.x=0
  o.y=0
  o.z=-1000
  for x=-100 to 100
    for y=-100 to 100
      d.x=x
      d.y=y
      d.z=1000
      kl=render( o.x,o.y,o.z , d.x,d.y,d.z , 7 )
      call setpixel x+winx/2,y+winy/2,kl
    next y
  next x
wait
[quit]
  close #m
end

function render( o.x,o.y,o.z , d.x,d.y,d.z , dept )
  scan
  low = infinity
  isph = -1
  for i = 0 to sphtel
    dist = hit(i , o.x,o.y,o.z , d.x,d.y,d.z )
    if dist < low then
      low = dist
      isph = i
    end if
  next i
  if isph = -1 then exit function
  call maal d.x,d.y,d.z , d.x,d.y,d.z , low
  call plus p.x,p.y,p.z , o.x,o.y,o.z , d.x,d.y,d.z
  c.x=sph(isph,t.x)
  c.y=sph(isph,t.y)
  c.z=sph(isph,t.z)
  call minus n.x,n.y,n.z , p.x,p.y,p.z , c.x,c.y,c.z
  angle=getangle( n.x,n.y,n.z , -1,1,-1 )
  kl=sph(isph,t.diffuse)
  render=mix(kl,cos(angle)/2+.5,0)
end function
function rgb(r,g,b)
  r=r and 255
  g=g and 255
  b=b and 255
  rgb=r+g*256+b*256^2
end function
sub setpixel x , y , kl
  r=int(kl)and 255
  g=int(kl/256)and 255
  b=int(kl/256^2)and 255
  #m "color ";r;" ";g;" ";b
  #m "goto ";x;" ";y
  #m "down"
  #m "set ";x;" ";y
  #m "up"
end sub
function mix(kl1,f,kl2)
  r1=int(kl1)and 255
  g1=int(kl1/256)and 255
  b1=int(kl1/256^2)and 255
  r2=int(kl2)and 255
  g2=int(kl2/256)and 255
  b2=int(kl2/256^2)and 255
  r=r1+(r2-r1)*f
  g=g1+(g2-g1)*f
  b=b1+(b2-b1)*f
  mix=rgb(r,g,b)
end function
sub minus byref a,byref b,byref c , x1,y1,z1 , x2,y2,z2
  a=x1-x2
  b=y1-y2
  c=z1-z2
end sub
sub plus byref a,byref b,byref c , x1,y1,z1 , x2,y2,z2
  a=x1+x2
  b=y1+y2
  c=z1+z2
end sub
sub maal byref a,byref b,byref c , x1,y1,z1 , q
  a=x1*q
  b=y1*q
  c=z1*q
end sub
sub div byref a,byref b,byref c , x1,y1,z1 , q
  a=x1/q
  b=y1/q
  c=z1/q
end sub
function getangle( a.x,a.y,a.z , b.x,b.y,b.z )
  la=lenght( a.x,a.y,a.z )
  lb=lenght( b.x,b.y,b.z )
  d=dot( a.x,a.y,a.z , b.x,b.y,b.z )
  getangle = acs(d/(la*lb))
end function
function lenght( a,b,c )
  lenght=sqr(dot(a,b,c,a,b,c))
end function
function dot( x1,y1,z1 , z2,y2,z2 )
  dot=x1*x2+y1*y2+z1*z2
end function
sub sphere x,y,z , d , kl,r
  sph(sphtel,t.x)=x
  sph(sphtel,t.y)=y
  sph(sphtel,t.z)=z
  sph(sphtel,t.d)=d
  sph(sphtel,t.d2)=d*d
  sph(sphtel,t.diffuse)=kl
  sph(sphtel,t.reflect)=r
  sphtel=sphtel+1
end sub
function hit( no , o.x,o.y,o.z , d.x,d.y,d.z )
  c.x=sph(no,t.x)
  c.y=sph(no,t.y)
  c.z=sph(no,t.z)
  call minus p.x,p.y,p.z , o.x,o.y,o.z , c.x,c.y,c.z
  a = dot( d.x,d.y,d.z , d.x,d.y,d.z )
  b = 2 * dot( p.x,p.y,p.z , d.x,d.y,d.z )
  c = dot( p.x,p.y,p.z , p.x,p.y,p.z ) - sph(no,t.d2)
  disc = b ^ 2 - 4 * a * c
  if disc < 0 then
    hit = inifity
    exit function
  else
    e = sqr( disc )
    demon = 2 * a
    t = ( 0-b - e ) / demon
    if t > 1e-12 then
      hit = t
      exit function
    end if

    t = ( 0-b + e ) / demon
    if t > 1e-12 then
      hit = t
      exit function
    end if
  end if
  hit = infinity
end function
 

Re: ray casting 2.0
Post by Brandon Parker on Jan 5th, 2018, 10:38pm

Looks to me like the program is attempting to retrieve the square root of a negative number.

This occurs on the first call to the "lenght" function within the following "getangle" function.

Code:
function getangle( a.x,a.y,a.z , b.x,b.y,b.z )
  la=lenght( a.x,a.y,a.z )
  lb=lenght( b.x,b.y,b.z )
  d=dot( a.x,a.y,a.z , b.x,b.y,b.z )
  getangle = acs(d/(la*lb))
end function 


When this occurs the "dot" function returns a negative number and the "lenght" function attempts to get the square root of that number. The fact that the number is negative is throwing the "Float invalid operation" error.


{:0)

Brandon Parker
Re: ray casting 2.0
Post by Rod on Jan 6th, 2018, 03:59am

I believe you only need the ABS() length. But that then leads to an arcsin out of range error. Do you need to normalise the values before calculating the angle? But I only guess.

You really need to take one set of known points through the calculations and be sure they are returning what you expect.