Liberty BASIC Community Forum
« ray casting 2.0 »

Welcome Guest. Please Login or Register.
Jan 23rd, 2018, 7:48pm


Rules|Home|Help|Search|Recent Posts|Notification


« Previous Topic | Next Topic »
Pages: 1 2  Notify Send Topic Print
 hotthread  Author  Topic: ray casting 2.0  (Read 573 times)
bluatigro
Guru
ImageImageImageImageImage


member is offline

Avatar

cxiu diversas el tio respondas cxiu samvaloras [ thats esperanto for : we are al different therefore we are al equal ]


PM

Gender: Male
Posts: 936
xx ray casting 2.0
« Thread started 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
 
User IP Logged

basic's : C64 Simons C128 Amiga Amos quick4.5 Visual5 Visual6 Visual2005 Visual2008 just and last but not least liberty
bluatigro
Guru
ImageImageImageImageImage


member is offline

Avatar

cxiu diversas el tio respondas cxiu samvaloras [ thats esperanto for : we are al different therefore we are al equal ]


PM

Gender: Male
Posts: 936
xx Re: ray casting 2.0
« Reply #1 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
 
User IP Logged

basic's : C64 Simons C128 Amiga Amos quick4.5 Visual5 Visual6 Visual2005 Visual2008 just and last but not least liberty
bluatigro
Guru
ImageImageImageImageImage


member is offline

Avatar

cxiu diversas el tio respondas cxiu samvaloras [ thats esperanto for : we are al different therefore we are al equal ]


PM

Gender: Male
Posts: 936
xx Re: ray casting 2.0
« Reply #2 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

 
User IP Logged

basic's : C64 Simons C128 Amiga Amos quick4.5 Visual5 Visual6 Visual2005 Visual2008 just and last but not least liberty
bluatigro
Guru
ImageImageImageImageImage


member is offline

Avatar

cxiu diversas el tio respondas cxiu samvaloras [ thats esperanto for : we are al different therefore we are al equal ]


PM

Gender: Male
Posts: 936
xx Re: ray casting 2.0
« Reply #3 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
 
User IP Logged

basic's : C64 Simons C128 Amiga Amos quick4.5 Visual5 Visual6 Visual2005 Visual2008 just and last but not least liberty
bluatigro
Guru
ImageImageImageImageImage


member is offline

Avatar

cxiu diversas el tio respondas cxiu samvaloras [ thats esperanto for : we are al different therefore we are al equal ]


PM

Gender: Male
Posts: 936
xx Re: ray casting 2.0
« Reply #4 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

 
User IP Logged

basic's : C64 Simons C128 Amiga Amos quick4.5 Visual5 Visual6 Visual2005 Visual2008 just and last but not least liberty
bluatigro
Guru
ImageImageImageImageImage


member is offline

Avatar

cxiu diversas el tio respondas cxiu samvaloras [ thats esperanto for : we are al different therefore we are al equal ]


PM

Gender: Male
Posts: 936
xx Re: ray casting 2.0
« Reply #5 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

 
User IP Logged

basic's : C64 Simons C128 Amiga Amos quick4.5 Visual5 Visual6 Visual2005 Visual2008 just and last but not least liberty
Rod
Global Moderator
ImageImageImageImageImage


member is offline

Avatar

Graphics = goosebumps!


PM

Gender: Male
Posts: 5618
xx Re: ray casting 2.0
« Reply #6 on: Nov 23rd, 2016, 06:17am »

Your angle value never seems to change so the sphere is monotone.
User IP Logged

bluatigro
Guru
ImageImageImageImageImage


member is offline

Avatar

cxiu diversas el tio respondas cxiu samvaloras [ thats esperanto for : we are al different therefore we are al equal ]


PM

Gender: Male
Posts: 936
xx Re: ray casting 2.0
« Reply #7 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

 
User IP Logged

basic's : C64 Simons C128 Amiga Amos quick4.5 Visual5 Visual6 Visual2005 Visual2008 just and last but not least liberty
Rod
Global Moderator
ImageImageImageImageImage


member is offline

Avatar

Graphics = goosebumps!


PM

Gender: Male
Posts: 5618
xx Re: ray casting 2.0
« Reply #8 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.
User IP Logged

bluatigro
Guru
ImageImageImageImageImage


member is offline

Avatar

cxiu diversas el tio respondas cxiu samvaloras [ thats esperanto for : we are al different therefore we are al equal ]


PM

Gender: Male
Posts: 936
xx ray casting 3.0
« Reply #9 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
User IP Logged

basic's : C64 Simons C128 Amiga Amos quick4.5 Visual5 Visual6 Visual2005 Visual2008 just and last but not least liberty
bluatigro
Guru
ImageImageImageImageImage


member is offline

Avatar

cxiu diversas el tio respondas cxiu samvaloras [ thats esperanto for : we are al different therefore we are al equal ]


PM

Gender: Male
Posts: 936
xx Re: ray casting 2.0
« Reply #10 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

 
User IP Logged

basic's : C64 Simons C128 Amiga Amos quick4.5 Visual5 Visual6 Visual2005 Visual2008 just and last but not least liberty
bluatigro
Guru
ImageImageImageImageImage


member is offline

Avatar

cxiu diversas el tio respondas cxiu samvaloras [ thats esperanto for : we are al different therefore we are al equal ]


PM

Gender: Male
Posts: 936
xx Re: ray casting 2.0
« Reply #11 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

 
User IP Logged

basic's : C64 Simons C128 Amiga Amos quick4.5 Visual5 Visual6 Visual2005 Visual2008 just and last but not least liberty
bluatigro
Guru
ImageImageImageImageImage


member is offline

Avatar

cxiu diversas el tio respondas cxiu samvaloras [ thats esperanto for : we are al different therefore we are al equal ]


PM

Gender: Male
Posts: 936
xx Re: ray casting 2.0
« Reply #12 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

 
User IP Logged

basic's : C64 Simons C128 Amiga Amos quick4.5 Visual5 Visual6 Visual2005 Visual2008 just and last but not least liberty
bluatigro
Guru
ImageImageImageImageImage


member is offline

Avatar

cxiu diversas el tio respondas cxiu samvaloras [ thats esperanto for : we are al different therefore we are al equal ]


PM

Gender: Male
Posts: 936
xx Re: ray casting 2.0
« Reply #13 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
 
User IP Logged

basic's : C64 Simons C128 Amiga Amos quick4.5 Visual5 Visual6 Visual2005 Visual2008 just and last but not least liberty
Brandon Parker
Board Moderator

member is offline

Avatar




PM

Gender: Male
Posts: 1123
xx Re: ray casting 2.0
« Reply #14 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
User IP Logged

Windows 7 Home Premium 64-bit Intel(R) Quad Core(TM) i5 CPU M 430 @ 2.27GHz 4GB DDR3 RAM
Pages: 1 2  Notify Send Topic Print
« Previous Topic | Next Topic »

Rules|Home|Help|Search|Recent Posts|Notification

Donate $6.99 for 50,000 Ad-Free Pageviews!

| |

This forum powered for FREE by Conforums ©
Sign up for your own Free Message Board today!
Terms of Service | Privacy Policy | Conforums Support | Parental Controls