raytrace try

General FreeBASIC programming questions.
bluatigro
Posts: 660
Joined: Apr 25, 2012 10:35
Location: netherlands

raytrace try

Post by bluatigro »

this is a try translating a c++ example

c++ code at :
https://sdm.scad.edu/faculty/mkesson/vs ... racer.html

error :
where is my yellow sphere ?
where is my shading ?
where is the shadow ?

Code: Select all

'' bluatigro 20 sept 2017
'' raytracer
''https://sdm.scad.edu/faculty 
''/mkesson/vsfx419/wip/best/winter12/jonathan_mann/raytracer.html


const as double infinity = 1e300
const as double small = 1e-300


type dbl3d
  x as double
  y as double
  z as double
  declare constructor()
  declare constructor ( x as double , y as double, z as double )
  declare sub fill( x as double , y as double , z as double )
  declare sub normalize
  declare function toColor() as ulong
end type
constructor dbl3d()
  this.x = 0
  this.y = 0
  this.z = 0
end constructor 
constructor dbl3d( x as double , y as double , z as double )
  this.x = x
  this.y = y
  this.z = z
end constructor 
operator <>( a as dbl3d , b as dbl3d ) as integer
  return a.x <> b.x or a.y <> b.y or a.z <> b.z
end operator
operator +( a as dbl3d , b as dbl3d ) as dbl3d
  return type( a.x + b.x , a.y + b.y , a.z + b.z )
end operator
operator *( a as dbl3d , d as double ) as dbl3d
  return type( a.x * d , a.y * d , a.z * d )
end operator
operator \( a as dbl3d , b as dbl3d ) as dbl3d
  return type( a.y * b.z - a.z * b.y _
             , a.z * b.x - a.x * b.z _
             , a.x * b.y - a.y * b.x )
end operator
operator -( a as dbl3d , b as dbl3d ) as dbl3d
  return type( a.x - b.x , a.y - b.y , a.z - b.z )
end operator
operator /( a as dbl3d , d as double ) as dbl3d
  return type( a.x / d , a.y / d , a.z / d )
end operator
sub dbl3d.fill( x as double , y as double , z as double )
  this.x = x
  this.y = y
  this.z = z
end sub
declare function dot( a as dbl3d , b as dbl3d ) as double
function dot( a as dbl3d , b as dbl3d ) as double
  return a.x * b.x + a.y * b.y + a.z * b.z
end function
function length( q as dbl3d ) as double
   return sqr( q.x * q.x + q.y * q.y + q.z * q.z ) + 1e-7
end function  
function normalize( q as dbl3d ) as dbl3d
  return q / length( q )
end function
function getangle( a as dbl3d , b as dbl3d ) as double
  a = normalize( a )
  b = normalize( b )
  return acos( dot( a , b ) _
  / ( length( a ) * length( b ) ) )
end function
function dbl3d.toColor() as ulong
  dim as integer r , g , b
  r = cint( x * 255 ) and 255
  g = cint( y * 255 ) and 255
  b = cint( z * 255 ) and 255
  return rgb( r , g , b )
end function
function dbl3dmix( a as dbl3d , f as double , b as dbl3d ) as dbl3d
  if f < 0 then return a
  if f > 1 then return b
  return a + ( b - a ) * f
end function
dim shared as dbl3d light
light.fill -1 , 1 , -1
type tmaterial
  dim as dbl3d diffuse
end type
dim shared as tmaterial material
type tSphere
  dim as dbl3d center
  dim as tmaterial mat
  dim as double radius , radius2
  declare sub fill( c as dbl3d , r as double )
  declare function hit( o as dbl3d, d as dbl3d ) as double 
  declare function normal( nu as dbl3d ) as dbl3d
end type
sub tSphere.fill( c as dbl3d , r as double )
''  spot c.x , c.y , c.z
  center = c
  radius = r
  radius2 = r * r
  mat = material
end sub
function tSphere.hit( o as dbl3d , d as dbl3d ) as double
  dim as double t , a , b , c , disc
  dim as dbl3d temp = o - center
  a = dot( d , d )
  b = 2 * dot( temp , d )
  c = dot( temp , temp ) - radius2
  disc = b ^ 2 - 4 * a * c
  if disc < 0 then 
    return infinity
  else
    dim as double e = sqr( disc ) 
    dim as double demon = 2 * a
    t = ( -b - e ) / demon
    if t > small then
      return t
    end if
    t = ( -b + e ) / demon
    if t > small then 
      return t
    end if
  end if
  return infinity
end function
dim shared as integer sphtel
dim shared as tsphere spheres( 100 )
sub add_sphere( x as double , y as double , z as double _
  , r as double , kl as dbl3d )
  material.diffuse = kl
  spheres( sphtel ).fill dbl3d( x , y , z ) , r
  sphtel += 1
end sub
function renderPixel( o as dbl3d , d as dbl3d _
  , depth as integer ) as dbl3d
  dim as double sphdist = infinity , q
  dim as integer isph = -1 , i
  for i = 0 to sphtel
    q = spheres( i ).hit( o , d )
    if q < sphdist then
      sphdist = q
      isph = i
    end if
  next i
  if isph = -1 then return dbl3d()
  dim as dbl3d p = o + normalize( d ) * sphdist
  dim as dbl3d n = p - spheres( isph ).center
  q = getangle( n , light )
  dim as dbl3d kl = spheres( isph ).mat.diffuse
  kl = kl * ( .5 + cos( q ) / 2 )
  for i = 0 to sphtel
    if i <> isph then
      q = spheres( i ).hit( p , light - p )
      if q < infinity then kl = dbl3d()
    end if
  next i      
  return kl
end function 

screen 20 , 32
dim as integer winx , winy
screeninfo winx , winy
dim as dbl3d o , d
dim as double x , y
sphtel = 0
add_sphere 0 , 0 , 0 , 250 , dbl3d( 0 , 1 , 1 )
add_sphere -200,200,-200, 30 , dbl3d( 1 , 1 , 0 )
for x = -winx / 2 to winx / 2
  for y = -winy / 2 to winy / 2
    o.fill 0 , 0 , -1000
    d.fill x , y , 1000
    pset( x + winx / 2 , winy / 2 - y ) _
    , renderPixel( o , d , 7 ).tocolor
  next y
next x
print "ready"
sleep 
bluatigro
Posts: 660
Joined: Apr 25, 2012 10:35
Location: netherlands

Re: raytrace try

Post by bluatigro »

update :
reflection added

how do i do :
specular , pong , refraction etc...

error :
where is my ground ?
where is my shading ?

Code: Select all

'' bluatigro 20 sept 2017
'' raytracer
''https://sdm.scad.edu/faculty 
''/mkesson/vsfx419/wip/best/winter12/jonathan_mann/raytracer.html


const as double infinity = 1e300
const as double small = 1e-300


type dbl3d
  x as double
  y as double
  z as double
  declare constructor()
  declare constructor ( x as double , y as double, z as double )
  declare sub fill( x as double , y as double , z as double )
  declare sub normalize
  declare function toColor() as ulong
end type
constructor dbl3d()
  this.x = 0
  this.y = 0
  this.z = 0
end constructor 
constructor dbl3d( x as double , y as double , z as double )
  this.x = x
  this.y = y
  this.z = z
end constructor 
operator <>( a as dbl3d , b as dbl3d ) as integer
  return a.x <> b.x or a.y <> b.y or a.z <> b.z
end operator
operator +( a as dbl3d , b as dbl3d ) as dbl3d
  return type( a.x + b.x , a.y + b.y , a.z + b.z )
end operator
operator *( a as dbl3d , d as double ) as dbl3d
  return type( a.x * d , a.y * d , a.z * d )
end operator
operator \( a as dbl3d , b as dbl3d ) as dbl3d
  return type( a.y * b.z - a.z * b.y _
             , a.z * b.x - a.x * b.z _
             , a.x * b.y - a.y * b.x )
end operator
operator -( a as dbl3d , b as dbl3d ) as dbl3d
  return type( a.x - b.x , a.y - b.y , a.z - b.z )
end operator
operator /( a as dbl3d , d as double ) as dbl3d
  return type( a.x / d , a.y / d , a.z / d )
end operator
sub dbl3d.fill( x as double , y as double , z as double )
  this.x = x
  this.y = y
  this.z = z
end sub
declare function dot( a as dbl3d , b as dbl3d ) as double
function dot( a as dbl3d , b as dbl3d ) as double
  return a.x * b.x + a.y * b.y + a.z * b.z
end function
function length( q as dbl3d ) as double
   return sqr( q.x * q.x + q.y * q.y + q.z * q.z ) + 1e-7
end function  
function normalize( q as dbl3d ) as dbl3d
  return q / length( q )
end function
function getangle( a as dbl3d , b as dbl3d ) as double
  a = normalize( a )
  b = normalize( b )
  return acos( dot( a , b ) _
  / ( length( a ) * length( b ) ) )
end function
function dbl3d.toColor() as ulong
  dim as integer r , g , b
  r = cint( x * 255 ) and 255
  g = cint( y * 255 ) and 255
  b = cint( z * 255 ) and 255
  return rgb( r , g , b )
end function
function dbl3dmix( a as dbl3d , f as double , b as dbl3d ) as dbl3d
  if f < 0 then return a
  if f > 1 then return b
  return a + ( b - a ) * f
end function
dim shared as dbl3d light
light.fill -1 , 1 , -1
type tmaterial
  dim as dbl3d diffuse
  dim as double reflection
end type
dim shared as tmaterial material
type tSphere
  dim as dbl3d center
  dim as tmaterial mat
  dim as double radius , radius2
  declare sub fill( c as dbl3d , r as double )
  declare function hit( o as dbl3d, d as dbl3d ) as double 
  declare function normal( nu as dbl3d ) as dbl3d
end type
sub tSphere.fill( c as dbl3d , r as double )
''  spot c.x , c.y , c.z
  center = c
  radius = r
  radius2 = r * r
  mat = material
end sub
function tSphere.hit( o as dbl3d , d as dbl3d ) as double
  dim as double t , a , b , c , disc
  dim as dbl3d temp = o - center
  a = dot( d , d )
  b = 2 * dot( temp , d )
  c = dot( temp , temp ) - radius2
  disc = b ^ 2 - 4 * a * c
  if disc < 0 then 
    return infinity
  else
    dim as double e = sqr( disc ) 
    dim as double demon = 2 * a
    t = ( -b - e ) / demon
    if t > small then
      return t
    end if
    t = ( -b + e ) / demon
    if t > small then 
      return t
    end if
  end if
  return infinity
end function
dim shared as integer sphtel
dim shared as tsphere spheres( 100 )
sub add_sphere( x as double , y as double , z as double _
  , r as double , kl as dbl3d )
  material.diffuse = kl
  spheres( sphtel ).fill dbl3d( x , y , z ) , r
  sphtel += 1
end sub
function renderPixel( o as dbl3d , d as dbl3d _
  , depth as integer ) as dbl3d
  dim as double sphdist = infinity , q
  dim as integer isph = -1 , i
  if depth < 0 then return dbl3d()
  for i = 0 to sphtel
    q = spheres( i ).hit( o , d )
    if q < sphdist then
      sphdist = q
      isph = i
    end if
  next i
  if isph = -1 then return dbl3d()
  dim as dbl3d p = o + normalize( d ) * sphdist
  dim as dbl3d n = p - spheres( isph ).center
  q = getangle( n , light )
  dim as dbl3d kl = spheres( isph ).mat.diffuse
  kl = kl * ( .5 + cos( q ) / 2 )
  for i = 0 to sphtel
    if i <> isph then
      q = spheres( i ).hit( p , light - p )
      if q < infinity then kl = dbl3d()
    end if
  next i  
  q = spheres( isph ).mat.reflection
  if q > small then 
    dim as dbl3d flect = d - n * ( 2 * dot( d , n ) )
    kl = dbl3dmix( kl , q , renderPixel( p , flect , depth - 1 ) )
  end if
  return kl
end function 

screen 20 , 32
dim as integer winx , winy
screeninfo winx , winy
dim as dbl3d o , d
dim as double x , y
sphtel = 0
material.reflection = 0.5
'' floting cyan sphere
add_sphere 0 , 0 , 0 , 250 , dbl3d( 0 , 1 , 1 )
'' green ground
add_sphere 0,-infinity-winy/2,0, infinity , dbl3d( 0 , 1 , 0 )
for x = -winx / 2 to winx / 2
  for y = -winy / 2 to winy / 2
    o.fill 0 , 0 , -1000
    d.fill x , y , 1000
    pset( x + winx / 2 , winy / 2 - y ) _
    , renderPixel( o , d , 7 ).tocolor
  next y
next x
print "ready"
sleep 
bluatigro
Posts: 660
Joined: Apr 25, 2012 10:35
Location: netherlands

Re: raytrace try

Post by bluatigro »

update :
shadow added
3 light system
[ how do i do a n light system ? ]

error :
my reflection's are strange
see mirror1() and mirror2()

all help is welokome

Code: Select all

'' bluatigro 25 sept 2017
'' triangle | sphere - ray
'' light's

#include "t_3d.bas"
#include "basis_3d_m.bas"


DIM shared AS INTEGER winx, winy, bitdepth
screen 20 , 32
SCREENINFO winx , winy , bitdepth

dim shared as t3d pnt( 256 )
sub setpoint( no as integer , a as double _
  , b as double , c as double )
  if no < 0 or no > ubound( pnt ) then exit sub
  spot a , b , c
  pnt( no ).x = a
  pnt( no ).y = b
  pnt( no ).z = c
end sub
type tmaterial
  dim as t3d ambient , diffuse , specular , emision
  dim as double shininess , reflection
end type
dim shared as tmaterial material
type triangle
public :
  dim as t3d punt( 2 ) , n , led 
  dim as tmaterial mat
  declare sub fill( p1 as integer , p2 as integer _
  , p3 as integer )
  declare function hit( o as t3d , d as t3d ) as double
end type
sub triangle.fill( p1 as integer , p2 as integer _
  , p3 as integer )
  if p1 < 0 or p1 > ubound( pnt ) then exit sub
  if p2 < 0 or p2 > ubound( pnt ) then exit sub
  if p3 < 0 or p3 > ubound( pnt ) then exit sub
  punt( 0 ) = pnt( p1 )
  punt( 1 ) = pnt( p2 )
  punt( 2 ) = pnt( p3 )
  led = ( punt( 0 ) + punt( 1 ) + punt( 2 ) ) / 3
  n = ( punt( 2 ) - punt( 0 ) ) \ ( punt( 1 ) - punt( 0 ) )
  n *= -1
  n = normalize( n )
  mat = material
end sub
function triangle.hit( o as t3d , d as t3d ) as double
  dim as t3d e1 = punt( 1 ) - punt( 0 )
  dim as t3d e2 = punt( 2 ) - punt( 0 )
  dim as t3d p = d \ e2
  dim as double a = dot( e1 , p )
  if abs( a ) < 1e-9 then return 1e9
  dim as double f = 1 / a
  dim as t3d s = o - punt( 0 )
  dim as double u = f * dot( s , p )
  if u < 0 or u > 1 then return 1e9
  dim as t3d q = s \ e1
  dim as double v = f * dot( d , q )
  if v < 0 or u + v > 1 then return 1e9
  return f * dot( e2 , q )
end function

dim shared as triangle triangles( 1000 )
dim shared as integer tritel = 0
sub tri( p1 as integer , p2 as integer _
  , p3 as integer )
  triangles( tritel ).fill p1 , p2 , p3
  tritel += 1
end sub
sub quad( p1 as integer , p2 as integer _
  , p3 as integer , p4 as integer )
  tri p1 , p2 , p3 
  tri p1 , p3 , p4
end sub
type Tbox
  m as t3d
  d as t3d
end type
dim shared box as Tbox
sub setbox( mx as double , my as double _
  , mz as double , dx as double _
  , dy as double , dz as double )
  box.m.x = mx
  box.m.y = my
  box.m.z = mz
  box.d.x = dx
  box.d.y = dy
  box.d.z = dz
end sub
sub torus( a as integer , b as integer )
  dim i as double , j as double , i2 as double , j2 as double
  if a < 3 then a = 3 
  if a > 64 then a = 64
  if b < 3 then b = 3 
  if b > 64 then b = 64 
  dim mx as double , my as double , mz as double , dx as double , dy as double , dz as double 
  mx = box.m.x 
  my = box.m.y 
  mz = box.m.z 
  dx = box.d.x 
  dy = box.d.y 
  dz = box.d.z 
  for i = -PI to PI  step PI / a * 2 
    i2 = i + PI / a * 2 
    for j = -PI to PI step PI / b * 2 
      j2 = j + PI / b * 2 
      setpoint 0 _ 
      , mx + ( dx + dy * cos( i ) ) * cos( j ) _
      , my + ( dx + dy * cos( i ) ) * sin( j ) _
      , mz + sin( i ) * dz  
      setpoint 1 _
      , mx + ( dx + dy * cos( i ) ) * cos( j2 ) _
      , my + ( dx + dy * cos( i ) ) * sin( j2 ) _
      , mz + sin( i ) * dz 
      setpoint 2 _
      , mx + ( dx + dy * cos( i2 ) ) * cos( j2 ) _
      , my + ( dx + dy * cos( i2 ) ) * sin( j2 ) _
      , mz + sin( i2 ) * dz 
      setpoint 3 _ 
      , mx + ( dx + dy * cos( i2 ) ) * cos( j ) _
      , my + ( dx + dy * cos( i2 ) ) * sin( j ) _
      , mz + sin( i2 ) * dz 
      quad 0 , 1 , 2 , 3 
    next j
  next i
end sub
sub cube()
  setpoint 0 , box.m.x + box.d.x , box.m.y + box.d.y , box.m.z + box.d.z
  setpoint 1 , box.m.x + box.d.x , box.m.y + box.d.y , box.m.z - box.d.z
  setpoint 2 , box.m.x + box.d.x , box.m.y - box.d.y , box.m.z + box.d.z
  setpoint 3 , box.m.x + box.d.x , box.m.y - box.d.y , box.m.z - box.d.z
  setpoint 4 , box.m.x - box.d.x , box.m.y + box.d.y , box.m.z + box.d.z
  setpoint 5 , box.m.x - box.d.x , box.m.y + box.d.y , box.m.z - box.d.z
  setpoint 6 , box.m.x - box.d.x , box.m.y - box.d.y , box.m.z + box.d.z
  setpoint 7 , box.m.x - box.d.x , box.m.y - box.d.y , box.m.z - box.d.z
  quad 0 , 2 , 3 , 1 ''right
  quad 7 , 6 , 4 , 5 ''left
  quad 0 , 4 , 5 , 1 ''up
  quad 7 , 3 , 2 , 6 ''down
  quad 0 , 4 , 6 , 2 ''back
  quad 7 , 5 , 1 , 3 ''front
end sub
sub cilinder( sides as integer , dx as single , dy as single )
  dim f as single
  if sides < 3 then sides = 3
  if sides > 64 then sides = 64
  for f = 0 to sides + 2
    setpoint f , box.m.x + sin( f * pi * 2 / sides ) * box.d.x _
               , box.m.y - box.d.y _
               , box.m.z + cos( f * pi * 2 / sides ) * box.d.z
    setpoint f + sides + 1 , box.m.x + sin( f * pi * 2 / sides ) * dx _
                           , box.m.y + box.d.y _
                           , box.m.z + cos( f * pi * 2 / sides ) * dy
  next f
  for f = 0 to sides + 1
    quad f , f + 1 , f + 2 + sides , f + 1 + sides 
  next f
    setpoint 255 , 0 , box.m.y + box.d.y , 0
    for f = 0 to sides
        setpoint f , box.m.x + sin( f * pi * 2 / sides ) * dx _
               , box.m.y + box.d.y _
               , box.m.z + cos( f * pi * 2 / sides ) * dy  
    next f
    for f = 0 to sides
      tri 255 , f , f + 1 
    next f
    setpoint 255 , 0 , box.m.y - box.d.y , 0
    for f = 0 to sides + 2
        setpoint f , box.m.x - sin( f * pi * 2 / sides ) * box.d.x _
               , box.m.y - box.d.y _
               , box.m.z + cos( f * pi * 2 / sides ) * box.d.z  
    next f
    for f = 0 to sides + 2
      tri 255 , f , f + 1 
    next f
end sub

type tSphere
  dim as t3d center
  dim as tmaterial mat
  dim as double radius , radius2
  declare sub fill( c as t3d , r as double )
  declare function hit( o as t3d , d as t3d ) as double 
  declare function normal( nu as t3d ) as t3d
end type
sub tSphere.fill( c as t3d , r as double )
  spot c.x , c.y , c.z
  center = c
  radius = r
  radius2 = r * r
  mat = material
end sub
function tSphere.hit( o as t3d , d as t3d ) as double
  dim as double t , a , b , c , disc
  dim as t3d temp = o - center
  a = dot( d , d )
  b = 2 * dot( temp , d )
  c = dot( temp , temp ) - radius2
  disc = b ^ 2 - 4 * a * c
  if disc < 0 then 
    return 1e9
  else
    dim as double e = sqr( disc ) 
    dim as double demon = 2 * a
    t = ( -b - e ) / demon
    if t > 1e-12 then
      return t
    end if
    
    t = ( -b + e ) / demon
    if t > 1e-12 then 
      return t
    end if
  end if
  return 1e9
end function
function tSphere.normal( nu as t3d ) as t3d
  return nu - center
end function
dim shared as tSphere spheres( 1000 )
dim shared as integer spheretel
sub sphere2( c as t3d , r as double )
  spheres( spheretel ).fill c , r 
  spheretel += 1
end sub
sub sphere( a as double , b as double , c as double _
  , r as double , kl as t3d )
  material.diffuse = kl
  spheres( spheretel ).fill t3d( a , b , c ) , r
  spheretel += 1
end sub
function mirror1( d as t3d , q as t3d ) as t3d
  dim as double ha , hb
  ha = atan2( q.y , q.z ) * 180 / pi
  rotate q.y , q.z , -ha 
  rotate d.y , d.z , -ha 
  hb = atan2( q.x , q.z ) * 180 / pi
  rotate q.x , q.z , -hb 
  rotate d.x , d.z , -hb
  d.z *= -1
  rotate d.x , d.z , hb 
  rotate d.y , d.z , ha 
  return d
end function
function mirror2( d as t3d , q as t3d ) as t3d
  return d - q * ( 2 * dot( d , q ) )
end function
dim shared as t3d red_light , green_light , blue_light
type t_fog
  dim as t3d kl
  dim as double dist , height
  dim as integer visable
end type
dim shared as t_fog fog
function renderPixel( o as t3d , d as t3d _
  , dept as integer ) as t3d
  dim as integer i , id = -1 , id2 = -1 
  dim as double dist , tridist = 1e9 , sphdist = 1e9 
  dim as t3d kl , kl2 , ambient , diffuse _
  , specular , emision , q , p , shade , uit , a
  dim as double shininess , reflection
  for i = 0 to tritel
    dist = triangles( i ).hit( o , d )
    if dist > 0 andalso dist < tridist then
      id = i
      tridist = dist
    end if
  next i
  for i = 0 to spheretel
    dist = spheres( i ).hit( o , d )
    if dist > 0 andalso dist < sphdist then
      id2 = i
      sphdist = dist
    end if
  next i
  if tridist = 1e9 and sphdist = 1e9 then
    if fog.visable then
      return fog.kl
    else
      return t3d()
    end if
  end if
  if tridist < sphdist then 
    reflection = triangles( id ).mat.reflection
    ''color objects from triangle
    ''how do i calc the end color ?
    ambient = triangles( id ).mat.ambient
    diffuse = triangles( id ).mat.diffuse
    specular = triangles( id ).mat.specular
    emision = triangles( id ).mat.emision
    shininess = triangles( id ).mat.shininess
    a.x = angle( triangles( id ).n , red_light )
    a.y = angle( triangles( id ).n , green_light )
    a.z = angle( triangles( id ).n , blue_light )
    kl.x = diffuse.x * ( cos( a.x * 2 ) / 2 + 0.5 )
    kl.y = diffuse.y * ( cos( a.y * 2 ) / 2 + 0.5 )
    kl.z = diffuse.z * ( cos( a.z * 2 ) / 2 + 0.5 )
    if a.x > rad(90) then kl.x = 0
    if a.y > rad(90) then kl.y = 0
    if a.z > rad(90) then kl.z = 0
    p = o + d * tridist
    if fog.visable then
      kl = t3dmix( kl , tridist / 10 , fog.kl )
    end if
''    for i = 0 to tritel - 1
''      if i <> id then
''        if triangles(i).hit(p,red_light)<1e9 then kl.x = 0
''        if triangles(i).hit(p,green_light)<1e9 then kl.y = 0
''        if triangles(i).hit(p,blue_light)<1e9 then kl.z = 0
''      end if
''    next i
    for i = 0 to spheretel - 1
      if spheres(i).hit(p,red_light)<1e9 then kl.x = 0
      if spheres(i).hit(p,green_light)<1e9 then kl.y = 0
      if spheres(i).hit(p,blue_light)<1e9 then kl.z = 0
    next i
    if reflection < 0.0001 or dept < 0 then
      return kl
    else
      q = triangles( id ).n
      d = mirror1( d , q )
      ''d = mirror2( d , q )
      kl2 = renderPixel( p , d , dept - 1 )
      return t3dmix( kl , reflection , kl2 )
    end if
  else
    reflection = spheres( id2 ).mat.reflection
    ''color objects from sphere
    ''how do i calc the end color ?
    ambient = spheres( id2 ).mat.ambient
    diffuse = spheres( id2 ).mat.diffuse
    specular = spheres( id2 ).mat.specular
    emision = spheres( id2 ).mat.emision
    shininess = spheres( id2 ).mat.shininess
    p = o + d * sphdist
    q = spheres( id2 ).normal( p )
    q = normalize(q)
    a.x = angle( q , red_light )
    a.y = angle( q , green_light )
    a.z = angle( q , blue_light )
    kl.x = diffuse.x * ( cos( a.x * 2 ) / 2 + 0.5 )
    kl.y = diffuse.y * ( cos( a.y * 2 ) / 2 + 0.5 )
    kl.z = diffuse.z * ( cos( a.z * 2 ) / 2 + 0.5 )
    if a.x > rad(90) then kl.x = 0
    if a.y > rad(90) then kl.y = 0
    if a.z > rad(90) then kl.z = 0
    if fog.visable then
      kl = t3dmix( kl , sphdist / 10 , fog.kl )
    end if
    for i = 0 to tritel - 1
        if triangles(i).hit(p,red_light) <1e9 then kl.x = 0
        if triangles(i).hit(p,green_light)<1e9 then kl.y = 0
        if triangles(i).hit(p,blue_light)<1e9 then kl.z = 0
    next i
    for i = 0 to spheretel - 1
      if i <> id2 then
        if spheres(i).hit(p,red_light)<1e9 then kl.x = 0
        if spheres(i).hit(p,green_light)<1e9 then kl.y = 0
        if spheres(i).hit(p,blue_light)<1e9 then kl.z = 0
      end if
    next i
    
    if reflection < 0.001 or dept < 0 then
      return kl
    else
      d = mirror1( d , q )
      ''d = mirror2( d , q )
      kl2 = renderPixel( p , d , dept - 1 )
      return kl + ( kl2 - kl ) * reflection
    end if
  end if
  if fog.visable then return fog.kl
  return t3d()
end function
dim shared as t3d black , red , green , yellow , blue _
, magenta , cyan , white , gray , pink , orange
black.fill   0  , 0  , 0
red.fill     1  , 0  , 0
green.fill   0  , 1  , 0
yellow.fill  1  , 1  , 0
blue.fill    0  , 0  , 1
magenta.fill 1  , 0  , 1
cyan.fill    0  , 1  , 1
white.fill   1  , 1  , 1
gray.fill    .5 , .5 , .5
pink.fill    1  , .5 , .5
orange.fill  1  , .5 , 0

const as integer arm   = 1
const as integer elbow = 2
const as integer wrist = 3
const as integer leg   = 4
const as integer knee  = 5
const as integer enkle = 6
const as integer neck  = 7
const as integer eye   = 8
const as integer wenk  = 9
const as integer tail  = 10
const as integer thumb = 11
const as integer index = 14
const as integer midle = 17
const as integer ring  = 20
const as integer lr    = 32

Sub Kop( qq as integer , kl as t3d )
    link 15, 0, 0, 0, 0, 0, 0,xyz, number
        sphere 0, 0, 0, 30, kl
    If qq = 1 Then
        sphere 25, 25, 0, 9, kl
        sphere -25, 25, 0, 9, kl
        sphere 0, 0, -40, 12, gray
    Else
        sphere 30, 0, 0, 9, kl
        sphere -30, 0, 0, 9, kl
        sphere 0, 0, -40, 12, kl
    End If
        child 16, 14, 14, -14, eye ,xyz, 15
          sphere 0, 0, 0, 13, white
          sphere 0, 0, -10, 7, black
        child 16, -14, 14, -14, eye + lr,xyz, 15
          sphere 0, 0, 0, 13, white
          sphere 0, 0, -10, 7, black
End Sub


sub man( trui as t3d , broek as t3d )
    link 9 , 0,0,0 , 0,0,0 , xyz , number
        sphere 0, 50, 0, 30, trui
        sphere 0, 25, 0, 23, broek
        sphere 0, 0, 0, 15, broek
    child 11, 0, 70, 0, neck, xyz, 9
    child 12, 0, 30, 0, neck+lr, xyz, 11
        Kop 0, pink
    child 11, 20, -10, 0, leg, yzx, 9
        sphere 0, 0, 0, 16, broek
        sphere 0, -20, 0, 16, broek
    child 12, 0, -40, 0, knee, xyz, 11
        sphere 0, 0, 0, 16, broek
        sphere 0, -20, 0, 16, broek
    child 13, 0, -40, 0, enkle, xzy, 12
        sphere 0, 0, 0, 12, gray
        sphere 0, 0, -20, 12, gray
    child 11, -20, -10, 0, leg+lr , yzx, 9
        sphere 0, 0, 0, 16, broek
        sphere 0, -20, 0, 16, broek
    child 12, 0, -40, 0, knee+lr, xyz, 11
        sphere 0, 0, 0, 16, broek
        sphere 0, -20, 0,16, broek
    child 13, 0, -40, 0,enkle+lr, xzy, 12
        sphere 0, 0, 0, 12, gray
        sphere 0, 0, -20, 12, gray
    child 11, 40, 60, 0, arm, xzy, 9
        sphere 0, 0, 0, 16, trui
        sphere 6, -20, 0, 12, trui
    child 12, 6, -40, 0, elbow, xyz, 11
        sphere 0, 0, 0, 12, trui
        sphere 0, -20, 0, 12, trui
        sphere 0, -42, 0, 8, pink
    child 11, -40, 60, 0, arm+lr, xzy, 9
        sphere 0, 0, 0, 16, trui
        sphere -6, -20, 0, 12, trui
    child 12, -6, -40, 0, elbow+lr, xyz, 11
        sphere 0, 0, 0, 12, trui
        sphere 0, -20, 0, 12, trui
        sphere 0, -42, 0, 8, pink
end sub
sub man_walk( f as double , a as double )
    skelet arm , pend( f , a ) , 0 , 0
    skelet elbow , -abs( a ) , 0 , 0
    skelet arm + lr , pend( f + 180, a ) , 0 , 0
    skelet elbow + lr , -abs( a ) , 0 , 0
    skelet leg , pend( f + 180 , a ) , 0 , 0
    skelet knee , pend( f + 90 , a ) + a , 0 , 0
    skelet leg + lr , pend( f , a ) , 0 , 0
    skelet knee + lr , pend( f - 90 , a ) + a , 0 , 0
end sub
sub dog_walk( f as double , a as double )
    skelet arm , pend( f , a ) , 0 , 0
    skelet elbow , pend( f - 90 , a ) + a , 0 , 0
    skelet arm + lr , pend( f + 180, a ) , 0 , 0
    skelet elbow + lr , pend( f + 90 , a ) + a , 0 , 0
    skelet leg , pend( f + 180 , a ) , 0 , 0
    skelet knee , pend( f + 90 , a ) + a , 0 , 0
    skelet leg + lr , pend( f , a ) , 0 , 0
    skelet knee + lr , pend( f - 90 , a ) + a , 0 , 0
    skelet tail , -a , pend( f * 2 , a ) , 0
end sub

sub pilko( kl as t3d )
  sphere 0,0,0,30 , kl
  sphere 0,0,50,30 , kl
  child 2 , 0,20,-20 , neck , xyz , 1
    child 3 , 0,20,-20 , neck , zyx , 2
      kop 1 , kl
  child 11, -20, -10, 50, leg, yzx, 1
    sphere 0, 0, 0, 16, kl
    sphere 0, -20, 0, 16, kl
    child 12, 0, -40, 0, knee, xyz, 11
      sphere 0, 0, 0, 16, kl
      sphere 0, -20, 0, 16, kl
      child 13, 0, -40, 0, enkle, xzy, 12
        sphere 0, 0, 0, 12, kl
        sphere 0, 0, -20, 12, kl
  child 11, 20, -10, 50, leg+lr, yzx, 1
    sphere 0, 0, 0, 16, kl
    sphere 0, -20, 0, 16, kl
    child 12, 0, -40, 0, knee+lr, xyz, 11
      sphere 0, 0, 0, 16, kl
      sphere 0, -20, 0, 16, kl
      child 13, 0, -40, 0, enkle+lr, xzy, 12
        sphere 0, 0, 0, 12, kl
        sphere 0, 0, -20, 12, kl
  child 11, 20, -10, 0, arm, yzx, 1
    sphere 0, 0, 0, 16, kl
    sphere 0, -20, 0, 16, kl
    child 12, 0, -40, 0, elbow, xyz, 11
      sphere 0, 0, 0, 16, kl
      sphere 0, -20, 0, 16, kl
      child 13, 0, -40, 0, wrist, xzy, 12
        sphere 0, 0, 0, 12, kl
        sphere 0, 0, -20, 12, kl
  child 11, -20, -10, 0, arm+lr, yzx, 1
    sphere 0, 0, 0, 16, kl
    sphere 0, -20, 0, 16, kl
    child 12, 0, -40, 0, elbow+lr, xyz, 11
      sphere 0, 0, 0, 16, kl
      sphere 0, -20, 0, 16, kl
      child 13, 0, -40, 0, wrist+lr, xzy, 12
        sphere 0, 0, 0, 12, kl
        sphere 0, 0, -20, 12, kl
  child 3 , 0,14,90 , tail , xyz , 2
    dim i as integer
    for i = 0 to 5
      sphere 0,i*8,0,10 , kl
    next i
end sub
sub saveframe( f as string , no as integer , m as integer )
  bsave f + nr( no , m ) + ".bmp" , 0
end sub
dim as double frame
''for frame = 0 to 35
red_light.fill -1 , 1 , 1
green_light.fill 0 , 1 , 0
blue_light.fill 1 , 1 , 1

tritel = 0
spheretel = 0
material.diffuse = white
link 1 , -400,0,-450 , 30,30,30 , xyz , 0
setbox 0,0,0 , 100,100,100
cube
''link 1 , 400,0,-450 , 30,30,30 , xyz , 0
''setbox 0,0,0 , 100,30,30
''torus 12 , 12
link 1 , 0,0,0 , 0,0,0 , xyz , 0
sphere 0,250,-450 , 100 , magenta
sphere -200,-186,-450 , 100 , yellow
sphere 200,-186,-450 , 100 , cyan
sphere 0,0,-1000 , 400 , white
sphere 0,-1e9-winy/2,0 , 1e9 , white
fog.visable = 0
fog.kl = gray
fog.dist = 10

dim as double x , y
dim as t3d o , d
paint( 1 , 1 ) , rgb( 255 , 255 , 255 )
for x = -winx / 2 to winx / 2
  for y = -winy / 2 to winy / 2
    o.fill 0 , 0 , 1000
    d.fill x , y , -1000
    pset( x + winx / 2 , winy / 2 - y ) _
    , renderPixel( o , d , 7 ).toColor
  next y
next x
''saveframe "bmp\man" , cint( frame ) , 3
bsave "3-light-2.bmp" , 0
''next frame
print "ready"
sleep
screen 0

Code: Select all

''bluatigro 21 okt 2015
''OOP game lib : some 3D vector math

#ifndef T3D_H
#define T3D_H

type t3d
  x as double
  y as double
  z as double
  declare constructor()
  declare constructor ( x as double , y as double, z as double )
  declare sub fill( x as double , y as double , z as double )
  declare function toColor() as ulong
end type
constructor t3d()
  this.x = 0
  this.y = 0
  this.z = 0
end constructor 
constructor t3d( x as double , y as double , z as double )
  this.x = x
  this.y = y
  this.z = z
end constructor 
operator <>( a as t3d , b as t3d ) as integer
  return a.x <> b.x or a.y <> b.y or a.z <> b.z
end operator
operator +( a as t3d , b as t3d ) as t3d
  return type( a.x + b.x , a.y + b.y , a.z + b.z )
end operator
operator *( a as t3d , d as double ) as t3d
  return type( a.x * d , a.y * d , a.z * d )
end operator
operator \( a as t3d , b as t3d ) as t3d
  return type( a.y * b.z - a.z * b.y _
             , a.z * b.x - a.x * b.z _
             , a.x * b.y - a.y * b.x )
end operator
operator -( a as t3d , b as t3d ) as t3d
  return type( a.x - b.x , a.y - b.y , a.z - b.z )
end operator
operator /( a as t3d , d as double ) as t3d
  return type( a.x / d , a.y / d , a.z / d )
end operator
sub t3d.fill( x as double , y as double , z as double )
  this.x = x
  this.y = y
  this.z = z
end sub
function dot( a as t3d , b as t3d ) as double
  return a.x * b.x + a.y * b.y + a.z * b.z
end function
function length( q as t3d ) as double
   return sqr( dot( q , q ) ) + 1e-30
end function  
function angle( a as t3d , b as t3d ) as double
  dim as double d , la , lb
  d = dot( a , b )
  la = length( a )
  lb = length( b )
  return acos( d / ( la * lb ) )
end function
function normalize( a as t3d ) as t3d
  return a / length( a )
end function
function t3d.toColor() as ulong
  dim as integer r , g , b
  r = cint( x * 255 ) and 255
  g = cint( y * 255 ) and 255
  b = cint( z * 255 ) and 255
  return rgb( r , g , b )
end function
function t3dmix( a as t3d , f as double , b as t3d ) as t3d
  if f < 0 then return a
  if f > 1 then return b
  return a + ( b - a ) * f
end function

#endif ''end of t3d

Code: Select all

'' bluatigro 25 sept 2017
'' graphics lib : 3d engine

#ifndef BASIC3D_H
#define BASIC3D_H

''math

const as double pi = atn( 1 ) * 4
const as double golden_ratio = ( sqr( 5 ) - 1 ) / 2

function rad( x as double ) as double
''help function degrees to radians 
  return x * pi / 180
end function

function range( l as double , h as double ) as double
  return rnd * ( h - l ) + l
end function

function irange( l as integer , h as integer ) as integer
  return cint( rnd * ( h - l + 1 ) + l
end function

function nr( no as ulong , m as integer ) as string
  return right( "0000000000" + str( no ) , m )
end function

''create matrix type to hold position & orentation
type matrix
  dim as double m( 3 , 3 )
end type
''create multyplycation operator for matrix
operator * ( a as matrix , b as matrix ) as matrix
  dim as integer i , j , k
  dim uit as matrix
  for i = 0 to 3
    for j = 0 to 3
''      uit.m( i , j ) = 0
      for k = 0 to 3
''        uit.m( i , j ) += a.m( i , k ) * b.m( k , j )
        uit.m( j , k ) += a.m( j , i ) * b.m( i , k )
      next k
    next j
  next i
  return uit
end operator 
''create array of matrix's
dim shared as matrix v( 20 )
''create unity matrix
v( 0 ).m( 0 , 0 ) = 1
v( 0 ).m( 1 , 1 ) = 1
v( 0 ).m( 2 , 2 ) = 1
v( 0 ).m( 3 , 3 ) = 1
''create array to hold skeletal angles
dim shared as double sk( 64 , 2 )
''create some stuf for 3D engine
declare sub link( no as integer , x as double , y as double , z as double _
, pan as double , tilt as double , rol as double , ax as integer , p as integer )
declare sub child( no as integer , x as double , y as double , z as double _
, lim as integer , ax as integer , p as integer )
declare sub spot( byref x as double , byref y as double , byref z as double )
declare sub rotate( byref k as double , byref l as double , deg as double )
dim shared as integer number
dim shared as double cam( 6 )
declare sub camara( x as double , y as double , z as double _
, pan as double , tilt as double , rol as double , zoom as double )
declare function pend( f as double , a as double ) as double
declare sub skelet( no as integer , x as double , y as double , z as double )

const as integer xyz = 0
const as integer xzy = 1
const as integer yxz = 2
const as integer yzx = 3
const as integer zxy = 4
const as integer zyx = 5
function pend( f as double , a as double ) as double
''pendular motion for animation
''looks verry natural
  return sin( rad( f ) ) * a
end function
sub skelet( lim as integer , x as double , y as double , z as double )
''set angles of skeletal lim
''for animated avatars
  if lim < 0 or lim > 64 then exit sub
  sk( lim , 0 ) = x
  sk( lim , 1 ) = y
  sk( lim , 2 ) = z
end sub
sub camera( x as double , y as double , z as double _
, pan as double , tilt as double , rol as double , zoom as double )
''set look from point & look angles
  cam( 0 ) = x
  cam( 1 ) = y
  cam( 2 ) = z
  cam( 3 ) = pan
  cam( 4 ) = tilt
  cam( 5 ) = rol
  cam( 6 ) = zoom
end sub
sub moveCamera( x as double , y as double , z as double _
  , pan as double )
  rotate x , z , cam( 3 )
  cam( 0 ) += x
  cam( 1 ) += y
  cam( 2 ) += z
  cam( 3 ) = ( cam( 3 ) + pan ) mod 360
end sub
Sub link( no As Integer, x As double, y As double, z As double, pan As double, tilt As double, rol As double, ax As Integer, p As Integer )
''set curent matrix wil afect folowing drawing comands
   If no < 1 Or no > 20 Then Exit Sub
   If p < 0 Or p > 20 Then Exit Sub
   If p = no Then Exit Sub
   ''create some lokal matrix's and fill them
   Dim As matrix mp, rotx, roty, rotz, translate
   mp = v( p )
   rotx = v( 0 )
   roty = v( 0 )
   rotz = v( 0 )
   translate = v( 0 )
   rotz.m( 0, 0 ) = Cos( rad( rol ))
   rotz.m( 0, 1 ) = -Sin( rad( rol ))
   rotz.m( 1, 0 ) = Sin( rad( rol ))
   rotz.m( 1, 1 ) = Cos( rad( rol ))
   roty.m( 0, 0 ) = Cos( rad( pan ))
   roty.m( 0, 2 ) = -Sin( rad( pan ))
   roty.m( 2, 0 ) = Sin( rad( pan ))
   roty.m( 2, 2 ) = Cos( rad( pan ))
   rotx.m( 1, 1 ) = Cos( rad( tilt ))
   rotx.m( 1, 2 ) = -Sin( rad( tilt ))
   rotx.m( 2, 1 ) = Sin( rad( tilt ))
   rotx.m( 2, 2 ) = Cos( rad( tilt ))
   translate.m( 3, 0 ) = x
   translate.m( 3, 1 ) = y
   translate.m( 3, 2 ) = z
   ''angles can permutate 6 ways
   Select Case ax
      Case xyz
         v( no ) = rotx * roty * rotz * translate * mp
      Case xzy
         v( no ) = rotx * rotz * roty * translate * mp
      Case yxz
         v( no ) = roty * rotx * rotz * translate * mp
      Case yzx
         v( no ) = roty * rotz * rotx * translate * mp
      Case zxy
         v( no ) = rotz * rotx * roty * translate * mp
      Case zyx
         v( no ) = rotz * roty * rotx * translate * mp
      Case Else
   End Select
   number = no
End Sub
sub child( no as integer , x as double , y as double , z as double _
, lim as integer , ax as integer , p as integer )
''set curent matrix for lim of animated avatar
''wil efect folowing drawings
  if lim < 0 or lim > 64 then exit sub
  link no , x , y , z _
  , sk( lim , 1 ) , sk( lim , 0 ) , sk( lim , 2 ), ax , p
end sub
sub spot( byref x as double , byref y as double , byref z as double )
''calulate world coordinates from lokal coordinates
''using curent matrix
  dim as double hx , hy , hz
  dim as integer i
  ''use curent matrix
  i = number
  hx = x * v( i ).m( 0 , 0 ) + y * v( i ).m( 1 , 0 ) _
  + z * v( i ).m( 2 , 0 ) + v( i ).m( 3 , 0 )
  hy = x * v( i ).m( 0 , 1 ) + y * v( i ).m( 1 , 1 ) _
  + z * v( i ).m( 2 , 1 ) + v( i ).m( 3 , 1 )
  hz = x * v( i ).m( 0 , 2 ) + y * v( i ).m( 1 , 2 ) _
  + z * v( i ).m( 2 , 2 ) + v( i ).m( 3 , 2 )
  x = hx 
  y = hy
  z = hz
  ''use camara matrix
  x += - cam( 0 )
  y += - cam( 1 )
  z += - cam( 2 )
  rotate x , z , -cam( 3 )
  rotate y , z , -cam( 4 )
  rotate x , y , -cam( 5 )
end sub
sub rotate( byref k as double , byref l as double , deg as double )
''help sub for rotating coordinates
 dim as double hk , hl , s , c
  s = sin( rad( deg ) )
  c = cos( rad( deg ) )
  hk = k * c - l * s
  hl = k * s + l * c
  k = hk
  l = hl
end sub

#endif

bluatigro
Posts: 660
Joined: Apr 25, 2012 10:35
Location: netherlands

Re: raytrace try

Post by bluatigro »

update :
procedural textures

error :
i see only my ground sphere not my sky sphere

main :

Code: Select all

''bluatigro 12 nov 2015
''triangle | sphere - ray

#include "t_3d.bas"
#include "basis_3d_m.bas"
#include "noise.bas"


DIM shared AS INTEGeR winx, winy, bitdepth
screen 20 , 32
SCREENINFO winx , winy , bitdepth

dim shared as t3d pnt( 256 )
sub setpoint( no as integer , a as double _
  , b as double , c as double )
  if no < 0 or no > ubound( pnt ) then exit sub
  spot a , b , c
  pnt( no ).x = a
  pnt( no ).y = b
  pnt( no ).z = c
end sub
const as integer mat_plain = 0
const as integer mat_wood = 1
const as integer mat_marble = 2
const as integer mat_turb = 3
type tmaterial
  dim as t3d kl( 10 ) , scale , translate
  dim as double reflection , turbulence
  dim as integer mattype , klmax , shadow
  declare constructor()
end type
constructor tmaterial()
  scale.fill 1,1,1
  shadow = 1
end constructor
dim shared as tmaterial material
type triangle
public :
  dim as t3d punt( 2 ) , n , led 
  dim as tmaterial mat
  declare sub fill( p1 as integer , p2 as integer _
  , p3 as integer )
  declare function hit( o as t3d , d as t3d ) as double
end type
sub triangle.fill( p1 as integer , p2 as integer _
  , p3 as integer )
  if p1 < 0 or p1 > ubound( pnt ) then exit sub
  if p2 < 0 or p2 > ubound( pnt ) then exit sub
  if p3 < 0 or p3 > ubound( pnt ) then exit sub
  punt( 0 ) = pnt( p1 )
  punt( 1 ) = pnt( p2 )
  punt( 2 ) = pnt( p3 )
  led = ( punt( 0 ) + punt( 1 ) + punt( 2 ) ) / 3
  n = ( punt( 2 ) - punt( 0 ) ) \ ( punt( 1 ) - punt( 0 ) )
  n *= -1
  n = normalize( n )
  mat = material
end sub
function triangle.hit( o as t3d , d as t3d ) as double
  dim as t3d e1 = punt( 1 ) - punt( 0 )
  dim as t3d e2 = punt( 2 ) - punt( 0 )
  dim as t3d p = d \ e2
  dim as double a = dot( e1 , p )
  if abs( a ) < 1e-9 then return -1
  dim as double f = 1 / a
  dim as t3d s = o - punt( 0 )
  dim as double u = f * dot( s , p )
  if u < 0 or u > 1 then return -1
  dim as t3d q = s \ e1
  dim as double v = f * dot( d , q )
  if v < 0 or u + v > 1 then return -1
  return f * dot( e2 , q )
end function

dim shared as triangle triangles( 1000 )
dim shared as integer tritel = 0
sub tri( p1 as integer , p2 as integer _
  , p3 as integer )
  triangles( tritel ).fill p1 , p2 , p3
  tritel += 1
end sub
sub quad( p1 as integer , p2 as integer _
  , p3 as integer , p4 as integer )
  tri p1 , p2 , p3 
  tri p1 , p3 , p4
end sub
type Tbox
  m as t3d
  d as t3d
end type
dim shared box as Tbox
sub setbox( mx as double , my as double _
  , mz as double , dx as double _
  , dy as double , dz as double )
  box.m.x = mx
  box.m.y = my
  box.m.z = mz
  box.d.x = dx
  box.d.y = dy
  box.d.z = dz
end sub
sub torus( a as integer , b as integer )
  dim i as double , j as double , i2 as double , j2 as double
  if a < 3 then a = 3 
  if a > 64 then a = 64
  if b < 3 then b = 3 
  if b > 64 then b = 64 
  dim mx as double , my as double , mz as double , dx as double , dy as double , dz as double 
  mx = box.m.x 
  my = box.m.y 
  mz = box.m.z 
  dx = box.d.x 
  dy = box.d.y 
  dz = box.d.z 
  for i = -PI to PI  step PI / a * 2 
    i2 = i + PI / a * 2 
    for j = -PI to PI step PI / b * 2 
      j2 = j + PI / b * 2 
      setpoint 0 _ 
      , mx + ( dx + dy * cos( i ) ) * cos( j ) _
      , my + ( dx + dy * cos( i ) ) * sin( j ) _
      , mz + sin( i ) * dz  
      setpoint 1 _
      , mx + ( dx + dy * cos( i ) ) * cos( j2 ) _
      , my + ( dx + dy * cos( i ) ) * sin( j2 ) _
      , mz + sin( i ) * dz 
      setpoint 2 _
      , mx + ( dx + dy * cos( i2 ) ) * cos( j2 ) _
      , my + ( dx + dy * cos( i2 ) ) * sin( j2 ) _
      , mz + sin( i2 ) * dz 
      setpoint 3 _ 
      , mx + ( dx + dy * cos( i2 ) ) * cos( j ) _
      , my + ( dx + dy * cos( i2 ) ) * sin( j ) _
      , mz + sin( i2 ) * dz 
      quad 0 , 1 , 2 , 3 
    next j
  next i
end sub
sub cube()
  setpoint 0 , box.m.x + box.d.x , box.m.y + box.d.y , box.m.z + box.d.z
  setpoint 1 , box.m.x + box.d.x , box.m.y + box.d.y , box.m.z - box.d.z
  setpoint 2 , box.m.x + box.d.x , box.m.y - box.d.y , box.m.z + box.d.z
  setpoint 3 , box.m.x + box.d.x , box.m.y - box.d.y , box.m.z - box.d.z
  setpoint 4 , box.m.x - box.d.x , box.m.y + box.d.y , box.m.z + box.d.z
  setpoint 5 , box.m.x - box.d.x , box.m.y + box.d.y , box.m.z - box.d.z
  setpoint 6 , box.m.x - box.d.x , box.m.y - box.d.y , box.m.z + box.d.z
  setpoint 7 , box.m.x - box.d.x , box.m.y - box.d.y , box.m.z - box.d.z
  quad 0 , 2 , 3 , 1 ''right
  quad 7 , 6 , 4 , 5 ''left
  quad 0 , 4 , 5 , 1 ''up
  quad 7 , 3 , 2 , 6 ''down
  quad 0 , 4 , 6 , 2 ''back
  quad 7 , 5 , 1 , 3 ''front
end sub
sub cilinder( sides as integer , dx as single , dy as single )
  dim f as single
  if sides < 3 then sides = 3
  if sides > 64 then sides = 64
  for f = 0 to sides + 2
    setpoint f , box.m.x + sin( f * pi * 2 / sides ) * box.d.x _
               , box.m.y - box.d.y _
               , box.m.z + cos( f * pi * 2 / sides ) * box.d.z
    setpoint f + sides + 1 , box.m.x + sin( f * pi * 2 / sides ) * dx _
                           , box.m.y + box.d.y _
                           , box.m.z + cos( f * pi * 2 / sides ) * dy
  next f
  for f = 0 to sides + 1
    quad f , f + 1 , f + 2 + sides , f + 1 + sides 
  next f
    setpoint 255 , 0 , box.m.y + box.d.y , 0
    for f = 0 to sides
        setpoint f , box.m.x + sin( f * pi * 2 / sides ) * dx _
               , box.m.y + box.d.y _
               , box.m.z + cos( f * pi * 2 / sides ) * dy  
    next f
    for f = 0 to sides
      tri 255 , f , f + 1 
    next f
    setpoint 255 , 0 , box.m.y - box.d.y , 0
    for f = 0 to sides + 2
        setpoint f , box.m.x - sin( f * pi * 2 / sides ) * box.d.x _
               , box.m.y - box.d.y _
               , box.m.z + cos( f * pi * 2 / sides ) * box.d.z  
    next f
    for f = 0 to sides + 2
      tri 255 , f , f + 1 
    next f
end sub

type tSphere
  dim as t3d center
  dim as tmaterial mat
  dim as double radius , radius2
  declare sub fill( c as t3d , r as double )
  declare function hit( o as t3d , d as t3d ) as double 
  declare function normal( nu as t3d ) as t3d
end type
sub tSphere.fill( c as t3d , r as double )
  spot c.x , c.y , c.z
  center = c
  radius = r
  radius2 = r * r
  mat = material
end sub
function tSphere.hit( o as t3d , d as t3d ) as double
  dim as double t , a , b , c , disc
  dim as t3d temp = o - center
  a = dot( d , d )
  b = 2 * dot( temp , d )
  c = dot( temp , temp ) - radius2
  disc = b ^ 2 - 4 * a * c
  if disc < 0 then 
    return -1
  else
    dim as double e = sqr( disc ) 
    dim as double demon = 2 * a
    t = ( -b - e ) / demon
    if t > 1e-12 then
      return t
    end if
    
    t = ( -b + e ) / demon
    if t > 1e-12 then 
      return t
    end if
  end if
  return -1
end function
function tSphere.normal( nu as t3d ) as t3d
  return nu - center
end function
dim shared as tSphere spheres( 1000 )
dim shared as integer spheretel
sub sphere2( c as t3d , r as double )
  spheres( spheretel ).fill c , r 
  spheretel += 1
end sub
sub sphere( a as double , b as double , c as double _
  , r as double , kl as t3d )
  material.kl( 0 ) = kl
  material.klmax = 0
  spheres( spheretel ).fill t3d( a , b , c ) , r
  spheretel += 1
end sub
function mirror( d as t3d , q as t3d ) as t3d
  dim as double ha , hb
  ha = atan2( q.y , q.z ) * 180 / pi
  rotate q.y , q.z , -ha 
  rotate d.y , d.z , -ha 
  hb = atan2( q.x , q.z ) * 180 / pi
  rotate q.x , q.z , -hb 
  rotate d.x , d.z , -hb
  d.z *= -1
  rotate d.x , d.z , hb 
  rotate d.y , d.z , ha 
  return d
end function
dim shared as t3d light
light.fill -1 , 3 , 1
type t_fog
  dim as t3d kl
  dim as double dist , height
  dim as integer visable
end type
dim shared as t_fog fog
function texture( x as double , y as double , z as double _
  , m as integer , t as double , i as integer ) as double
  dim as t3d s
  s = material.scale
  x /= s.x
  y /= s.y
  z /= s.z
  select case m
    case mat_turb
      return turbulence3d( x , y , z  , i )*t
    case mat_marble
      return sin( y + turbulence3d(x,y,z,i)*t ) / 2 + .5 
    case mat_wood
      return sin(sqr(x*x+z*z)+turbulence3d(x,y,z,i)*t)/2+.5
    case else
      return 0.0
  end select
end function
function renderPixel( o as t3d , d as t3d _
  , dept as integer ) as t3d
  dim as integer i , id = -1 , id2 = -1 
  dim as double dist , tridist = 1e9 , sphdist = 1e9 , a 
  dim as t3d kl1 , kl2 , q , p , shade , uit
  dim as double reflection , dd
  for i = 0 to tritel
    dist = triangles( i ).hit( o , d )
    if dist > 0 andalso dist < tridist then
      id = i
      tridist = dist
    end if
  next i
  for i = 0 to spheretel
    dist = spheres( i ).hit( o , d )
    if dist > 0 andalso dist < sphdist then
      id2 = i
      sphdist = dist
    end if
  next i
  if tridist = 1e9 and sphdist = 1e9 then
    if fog.visable then
      return fog.kl
    else
      return t3d()
    end if
  end if
  if tridist < sphdist then 
    reflection = triangles( id ).mat.reflection
    kl1 = triangles( id ).mat.kl( 0 )
    a = angle( triangles( id ).n , light )
    kl1 = kl1 * ( cos( a ) / 2 + 0.5 )
    p = o + d * tridist
    if fog.visable then
      kl1 = t3dmix( kl1 , tridist / 10 , fog.kl )
    end if
    return kl1
  else
    reflection = spheres( id2 ).mat.reflection
    p = o + d * sphdist
    q = spheres( id2 ).normal( p )
    p = q
    q = normalize(q)
    a = angle( q , light )
    i = spheres( id2 ).mat.klmax
    if i >= 1 then
      lokal p.x , p.y , p.z
      dd = texture( p.x , p.y , p.z _
      , spheres( id2 ).mat.mattype _
      , spheres( id2 ).mat.turbulence , 3 )
      i = i * dd
      kl1 = spheres( id2 ).mat.kl( i )
      kl2 = spheres( id2 ).mat.kl( i + 1 )
      kl1 = kl1 + ( kl2 - kl1 ) * dd 
    end if
    if spheres( id2 ).mat.shadow  then
      kl1 = kl1 * ( cos( a ) / 2 + 0.5 )
    end if
    if fog.visable then
      kl1 = t3dmix( kl1 , sphdist / 10 , fog.kl )
    end if
    if reflection < 0.001 or dept < 0 then
      return kl1
    else
      d = mirror( d , q )
      kl2 = renderPixel( p , d , dept - 1 )
      return kl1 + ( kl2 - kl1 ) * reflection
    end if
  end if
  if fog.visable then return fog.kl
  return t3d()
end function
dim shared as t3d black , red , green , yellow , blue _
, magenta , cyan , white , gray , pink , orange
black.fill   0  , 0  , 0
red.fill     1  , 0  , 0
green.fill   0  , 1  , 0
yellow.fill  1  , 1  , 0
blue.fill    0  , 0  , 1
magenta.fill 1  , 0  , 1
cyan.fill    0  , 1  , 1
white.fill   1  , 1  , 1
gray.fill    .5 , .5 , .5
pink.fill    1  , .5 , .5
orange.fill  1  , .5 , 0

const as integer arm   = 1
const as integer elbow = 2
const as integer wrist = 3
const as integer leg   = 4
const as integer knee  = 5
const as integer enkle = 6
const as integer neck  = 7
const as integer eye   = 8
const as integer wenk  = 9
const as integer tail  = 10
const as integer thumb = 11
const as integer index = 14
const as integer midle = 17
const as integer ring  = 20
const as integer lr    = 32

Sub Kop( qq as integer , kl as t3d )
    link 15, 0, 0, 0, 0, 0, 0,xyz, number
        sphere 0, 0, 0, 30, kl
    If qq = 1 Then
        sphere 25, 25, 0, 9, kl
        sphere -25, 25, 0, 9, kl
        sphere 0, 0, -40, 12, gray
    Else
        sphere 30, 0, 0, 9, kl
        sphere -30, 0, 0, 9, kl
        sphere 0, 0, -40, 12, kl
    End If
        child 16, 14, 14, -14, eye ,xyz, 15
          sphere 0, 0, 0, 13, white
          sphere 0, 0, -10, 7, black
        child 16, -14, 14, -14, eye + lr,xyz, 15
          sphere 0, 0, 0, 13, white
          sphere 0, 0, -10, 7, black
End Sub


sub man( trui as t3d , broek as t3d )
    link 9 , 0,0,0 , 0,0,0 , xyz , number
        sphere 0, 50, 0, 30, trui
        sphere 0, 25, 0, 23, broek
        sphere 0, 0, 0, 15, broek
    child 11, 0, 70, 0, neck, xyz, 9
    child 12, 0, 30, 0, neck+lr, xyz, 11
        Kop 0, pink
    child 11, 20, -10, 0, leg, yzx, 9
        sphere 0, 0, 0, 16, broek
        sphere 0, -20, 0, 16, broek
    child 12, 0, -40, 0, knee, xyz, 11
        sphere 0, 0, 0, 16, broek
        sphere 0, -20, 0, 16, broek
    child 13, 0, -40, 0, enkle, xzy, 12
        sphere 0, 0, 0, 12, gray
        sphere 0, 0, -20, 12, gray
    child 11, -20, -10, 0, leg+lr , yzx, 9
        sphere 0, 0, 0, 16, broek
        sphere 0, -20, 0, 16, broek
    child 12, 0, -40, 0, knee+lr, xyz, 11
        sphere 0, 0, 0, 16, broek
        sphere 0, -20, 0,16, broek
    child 13, 0, -40, 0,enkle+lr, xzy, 12
        sphere 0, 0, 0, 12, gray
        sphere 0, 0, -20, 12, gray
    child 11, 40, 60, 0, arm, xzy, 9
        sphere 0, 0, 0, 16, trui
        sphere 6, -20, 0, 12, trui
    child 12, 6, -40, 0, elbow, xyz, 11
        sphere 0, 0, 0, 12, trui
        sphere 0, -20, 0, 12, trui
        sphere 0, -42, 0, 8, pink
    child 11, -40, 60, 0, arm+lr, xzy, 9
        sphere 0, 0, 0, 16, trui
        sphere -6, -20, 0, 12, trui
    child 12, -6, -40, 0, elbow+lr, xyz, 11
        sphere 0, 0, 0, 12, trui
        sphere 0, -20, 0, 12, trui
        sphere 0, -42, 0, 8, pink
end sub
sub man_walk( f as double , a as double )
    skelet arm , pend( f , a ) , 0 , 0
    skelet elbow , -abs( a ) , 0 , 0
    skelet arm + lr , pend( f + 180, a ) , 0 , 0
    skelet elbow + lr , -abs( a ) , 0 , 0
    skelet leg , pend( f + 180 , a ) , 0 , 0
    skelet knee , pend( f + 90 , a ) + a , 0 , 0
    skelet leg + lr , pend( f , a ) , 0 , 0
    skelet knee + lr , pend( f - 90 , a ) + a , 0 , 0
end sub
sub dog_walk( f as double , a as double )
    skelet arm , pend( f , a ) , 0 , 0
    skelet elbow , pend( f - 90 , a ) + a , 0 , 0
    skelet arm + lr , pend( f + 180, a ) , 0 , 0
    skelet elbow + lr , pend( f + 90 , a ) + a , 0 , 0
    skelet leg , pend( f + 180 , a ) , 0 , 0
    skelet knee , pend( f + 90 , a ) + a , 0 , 0
    skelet leg + lr , pend( f , a ) , 0 , 0
    skelet knee + lr , pend( f - 90 , a ) + a , 0 , 0
    skelet tail , -a , pend( f * 2 , a ) , 0
end sub

sub pilko( kl as t3d )
  sphere 0,0,0,30 , kl
  sphere 0,0,50,30 , kl
  child 2 , 0,20,-20 , neck , xyz , 1
    child 3 , 0,20,-20 , neck , zyx , 2
      kop 1 , kl
  child 11, -20, -10, 50, leg, yzx, 1
    sphere 0, 0, 0, 16, kl
    sphere 0, -20, 0, 16, kl
    child 12, 0, -40, 0, knee, xyz, 11
      sphere 0, 0, 0, 16, kl
      sphere 0, -20, 0, 16, kl
      child 13, 0, -40, 0, enkle, xzy, 12
        sphere 0, 0, 0, 12, kl
        sphere 0, 0, -20, 12, kl
  child 11, 20, -10, 50, leg+lr, yzx, 1
    sphere 0, 0, 0, 16, kl
    sphere 0, -20, 0, 16, kl
    child 12, 0, -40, 0, knee+lr, xyz, 11
      sphere 0, 0, 0, 16, kl
      sphere 0, -20, 0, 16, kl
      child 13, 0, -40, 0, enkle+lr, xzy, 12
        sphere 0, 0, 0, 12, kl
        sphere 0, 0, -20, 12, kl
  child 11, 20, -10, 0, arm, yzx, 1
    sphere 0, 0, 0, 16, kl
    sphere 0, -20, 0, 16, kl
    child 12, 0, -40, 0, elbow, xyz, 11
      sphere 0, 0, 0, 16, kl
      sphere 0, -20, 0, 16, kl
      child 13, 0, -40, 0, wrist, xzy, 12
        sphere 0, 0, 0, 12, kl
        sphere 0, 0, -20, 12, kl
  child 11, -20, -10, 0, arm+lr, yzx, 1
    sphere 0, 0, 0, 16, kl
    sphere 0, -20, 0, 16, kl
    child 12, 0, -40, 0, elbow+lr, xyz, 11
      sphere 0, 0, 0, 16, kl
      sphere 0, -20, 0, 16, kl
      child 13, 0, -40, 0, wrist+lr, xzy, 12
        sphere 0, 0, 0, 12, kl
        sphere 0, 0, -20, 12, kl
  child 3 , 0,14,90 , tail , xyz , 2
    dim i as integer
    for i = 0 to 5
      sphere 0,i*8,0,10 , kl
    next i
end sub
sub saveframe( f as string , no as integer , m as integer )
  bsave f + nr( no , m ) + ".bmp" , 0
end sub
dim as double frame
''for frame = 0 to 35
tritel = 0
spheretel = 0


''matèrial.reflection = 0.5
link 2 , 0,0,0 , 0,0,0 , xyz , 0
material.kl(0) = green 
material.kl(1) = green / 2
material.scale.fill 10,10,10
material.shadow = 0
material.klmax = 2
material.turbulence = 1
material.mattype = mat_marble
sphere2 t3d( 0 , -1e5-winy/2 , 0 ) , 1e5
material.kl(0) = blue 
material.kl(1) = white 
material.kl(2) = gray 
material.klmax = 3
material.turbulence = 1
material.mattype = mat_turb
sphere2 t3d( 0 , 1e5+winy/2 , 0 ) , 1e5

fog.visable = 0
fog.kl = gray
fog.dist = 10

dim as double x , y
dim as t3d o , d
paint( 1 , 1 ) , rgb( 255 , 255 , 255 )
for x = -winx / 2 to winx / 2
  for y = -winy / 2 to winy / 2
    o.fill 0 , 0 , 1000
    d.fill x , y , -1000
    pset( x + winx / 2 , winy / 2 - y ) _
    , renderPixel( o , d , 7 ).toColor
  next y
next x
''saveframe "bmp\man" , cint( frame ) , 3
bsave "texture-test.bmp" , 0
''next frame
print "ready"
sleep
screen 0
noise.bas :

Code: Select all

'' bluatigro 29 nov 2017
'' noise

#ifndef __SIMPLENOISE_BI__
#define __SIMPLENOISE_BI__

dim shared as integer NOIZESIZE = 63

function noise( x as integer , y as integer , z as integer ) as double
  randomize x + 1000 * y + 1e6 * z
  return rnd 
end function

function smoothNoise1d(x as double) as double
  x=abs(x)
  dim as integer iX1=int(x)
  dim as integer iX2=ix1+1
  dim as double tx=x-iX1
  iX1 and= NOIZESIZE
  iX2 and= NOIZESIZE
  dim as double l=noise(iX1,0,0)
  dim as double r=noise(iX2,0,0)
  dim as double v=l + (r-l)*tx
  return v
end function

function smoothNoise2d(x as double, y as double) as double
  x=abs(x)
  y=abs(y)
  dim as integer iX1=int(x)
  dim as integer iY1=int(y)
  dim as integer iX2=ix1+1
  dim as integer iY2=iy1+1
  dim as double tx=x-iX1
  dim as double ty=y-iY1
  
  iX1 and= NOIZESIZE
  iX2 and= NOIZESIZE
  iY1 and= NOIZESIZE
  iY2 and= NOIZESIZE
  
  dim as double lt=noise(iX1,iY1,0)
  dim as double rt=noise(iX2,iY1,0)
  dim as double rb=noise(iX2,iY2,0)
  dim as double lb=noise(iX1,iY2,0)
  
  dim as double sxt=lt + (rt-lt)*tx
  dim as double sxb=lb + (rb-lb)*tx
  
  dim as double v=sxt+(sxb-sxt)*ty
  return v
end function

function smoothNoise3d(x as double, y as double, z as double) as double
  x=abs(x)
  y=abs(y)
  z=abs(z)
  dim as integer iX1=int(x)
  dim as integer iY1=int(y)
  dim as integer iZ1=int(z)
  dim as integer iX2=ix1+1
  dim as integer iY2=iy1+1
  dim as integer iZ2=iz1+1
  dim as double tx=x-iX1
  dim as double ty=y-iY1
  dim as double tz=z-iZ1
  
  iX1 and= NOIZESIZE
  iX2 and= NOIZESIZE
  iY1 and= NOIZESIZE
  iY2 and= NOIZESIZE
  iZ1 and= NOIZESIZE
  iZ2 and= NOIZESIZE
  
  dim as double ltf=noise(iX1,iY1,iZ1)
  dim as double rtf=noise(iX2,iY1,iZ1)
  dim as double rbf=noise(iX2,iY2,iZ1)
  dim as double lbf=noise(iX1,iY2,iZ1)
  dim as double sxtf=ltf + (rtf-ltf)*tx
  dim as double sxbf=lbf + (rbf-lbf)*tx
  
  dim as double ltb=noise(iX1,iY1,iZ2)
  dim as double rtb=noise(iX2,iY1,iZ2)
  dim as double rbb=noise(iX2,iY2,iZ2)
  dim as double lbb=noise(iX1,iY2,iZ2)
  dim as double sxtb = ltb + (rtb-ltb)*tx
  dim as double sxbb = lbb + (rbb-lbb)*tx
  
  dim as double vf = sxtf+(sxbf-sxtf)*ty
  dim as double vb = sxtb+(sxbb-sxtb)*ty
  dim as double v = vf + (vb-vf)*tz
   
  return v
end function

function turbulence1d(x as double, size as double) as double
  dim as double value, initialSize=any
  if size<1 then size=1
  initialSize = size
  while(size >= 1)
    value += smoothNoise1d(x / size) * size
    size /= 2.0
  wend
  value*=0.5
  return value/initialSize
end function

function turbulence2d(x as double, y as double, size as double) as double
  dim as double value, initialSize=any
  if size<1 then size=1
  initialSize = size
  while(size >= 1)
    value += smoothNoise2d(x / size, y / size) * size
    size /= 2.0
  wend
  value*=0.5
  return value/(initialSize-1)
end function

function turbulence3d(x as double, y as double, z as double, size as double) as double
  dim as double value, initialSize=any
  if size<1 then size=1
  initialSize = size
  while(size >= 1)
    value += smoothNoise3d(x / size, y / size, z/size) * size
    size /= 2.0
  wend
  value*=0.5
  return value/(initialSize-1)
end function

#endif ' __SIMPLENOISE_BI__
bluatigro
Posts: 660
Joined: Apr 25, 2012 10:35
Location: netherlands

Re: raytrace try

Post by bluatigro »

add to basic 3d m bas :

Code: Select all

sub lokal( byref x as double , byref y as double , byref z as double )
  dim as matrix q = inverse( v( number ) )
  dim as double hx,hy,hz
  hx = q.m(0,0)*x+q.m(1,0)*y+q.m(2,0)*z
  hy = q.m(0,1)*x+q.m(1,1)*y+q.m(2,1)*z
  hz = q.m(0,2)*x+q.m(1,2)*y+q.m(2,2)*z
  x = hx
  y = hy
  z = hz
end sub
bluatigro
Posts: 660
Joined: Apr 25, 2012 10:35
Location: netherlands

Re: raytrace try

Post by bluatigro »

update :
PLANET EARTH 2.0 !!

error :
i can't move my spheres from (0,0,0)
my colors don't fade form 1 to another

Code: Select all

''bluatigro 12 nov 2015
''triangle | sphere - ray

#include "t_3d.bas"
#include "basis_3d_m.bas"
#include "noise.bas"


DIM shared AS INTEGeR winx, winy, bitdepth
screen 20 , 32
SCREENINFO winx , winy , bitdepth

dim shared as t3d pnt( 256 )
sub setpoint( no as integer , a as double _
  , b as double , c as double )
  if no < 0 or no > ubound( pnt ) then exit sub
  spot a , b , c
  pnt( no ).x = a
  pnt( no ).y = b
  pnt( no ).z = c
end sub
type tmaterial
  dim as t3d kl( 10 ) , scale , translate
  dim as double reflection , turbulence
  dim as integer mattype , klmax , shadow , waves
  declare constructor()
end type
constructor tmaterial()
  scale.fill 1,1,1
  shadow = 1
  waves = 7
end constructor
dim shared as tmaterial material
type triangle
public :
  dim as t3d punt( 2 ) , n , led 
  dim as tmaterial mat
  declare sub fill( p1 as integer , p2 as integer _
  , p3 as integer )
  declare function hit( o as t3d , d as t3d ) as double
end type
sub triangle.fill( p1 as integer , p2 as integer _
  , p3 as integer )
  if p1 < 0 or p1 > ubound( pnt ) then exit sub
  if p2 < 0 or p2 > ubound( pnt ) then exit sub
  if p3 < 0 or p3 > ubound( pnt ) then exit sub
  punt( 0 ) = pnt( p1 )
  punt( 1 ) = pnt( p2 )
  punt( 2 ) = pnt( p3 )
  led = ( punt( 0 ) + punt( 1 ) + punt( 2 ) ) / 3
  n = ( punt( 2 ) - punt( 0 ) ) \ ( punt( 1 ) - punt( 0 ) )
  n *= -1
  n = normalize( n )
  mat = material
end sub
function triangle.hit( o as t3d , d as t3d ) as double
  dim as t3d e1 = punt( 1 ) - punt( 0 )
  dim as t3d e2 = punt( 2 ) - punt( 0 )
  dim as t3d p = d \ e2
  dim as double a = dot( e1 , p )
  if abs( a ) < 1e-9 then return -1
  dim as double f = 1 / a
  dim as t3d s = o - punt( 0 )
  dim as double u = f * dot( s , p )
  if u < 0 or u > 1 then return -1
  dim as t3d q = s \ e1
  dim as double v = f * dot( d , q )
  if v < 0 or u + v > 1 then return -1
  return f * dot( e2 , q )
end function

dim shared as triangle triangles( 1000 )
dim shared as integer tritel = 0
sub tri( p1 as integer , p2 as integer _
  , p3 as integer )
  triangles( tritel ).fill p1 , p2 , p3
  tritel += 1
end sub
sub quad( p1 as integer , p2 as integer _
  , p3 as integer , p4 as integer )
  tri p1 , p2 , p3 
  tri p1 , p3 , p4
end sub
type Tbox
  m as t3d
  d as t3d
end type
dim shared box as Tbox
sub setbox( mx as double , my as double _
  , mz as double , dx as double _
  , dy as double , dz as double )
  box.m.x = mx
  box.m.y = my
  box.m.z = mz
  box.d.x = dx
  box.d.y = dy
  box.d.z = dz
end sub
sub torus( a as integer , b as integer )
  dim i as double , j as double , i2 as double , j2 as double
  if a < 3 then a = 3 
  if a > 64 then a = 64
  if b < 3 then b = 3 
  if b > 64 then b = 64 
  dim mx as double , my as double , mz as double , dx as double , dy as double , dz as double 
  mx = box.m.x 
  my = box.m.y 
  mz = box.m.z 
  dx = box.d.x 
  dy = box.d.y 
  dz = box.d.z 
  for i = -PI to PI  step PI / a * 2 
    i2 = i + PI / a * 2 
    for j = -PI to PI step PI / b * 2 
      j2 = j + PI / b * 2 
      setpoint 0 _ 
      , mx + ( dx + dy * cos( i ) ) * cos( j ) _
      , my + ( dx + dy * cos( i ) ) * sin( j ) _
      , mz + sin( i ) * dz  
      setpoint 1 _
      , mx + ( dx + dy * cos( i ) ) * cos( j2 ) _
      , my + ( dx + dy * cos( i ) ) * sin( j2 ) _
      , mz + sin( i ) * dz 
      setpoint 2 _
      , mx + ( dx + dy * cos( i2 ) ) * cos( j2 ) _
      , my + ( dx + dy * cos( i2 ) ) * sin( j2 ) _
      , mz + sin( i2 ) * dz 
      setpoint 3 _ 
      , mx + ( dx + dy * cos( i2 ) ) * cos( j ) _
      , my + ( dx + dy * cos( i2 ) ) * sin( j ) _
      , mz + sin( i2 ) * dz 
      quad 0 , 1 , 2 , 3 
    next j
  next i
end sub
sub cube()
  setpoint 0 , box.m.x + box.d.x , box.m.y + box.d.y , box.m.z + box.d.z
  setpoint 1 , box.m.x + box.d.x , box.m.y + box.d.y , box.m.z - box.d.z
  setpoint 2 , box.m.x + box.d.x , box.m.y - box.d.y , box.m.z + box.d.z
  setpoint 3 , box.m.x + box.d.x , box.m.y - box.d.y , box.m.z - box.d.z
  setpoint 4 , box.m.x - box.d.x , box.m.y + box.d.y , box.m.z + box.d.z
  setpoint 5 , box.m.x - box.d.x , box.m.y + box.d.y , box.m.z - box.d.z
  setpoint 6 , box.m.x - box.d.x , box.m.y - box.d.y , box.m.z + box.d.z
  setpoint 7 , box.m.x - box.d.x , box.m.y - box.d.y , box.m.z - box.d.z
  quad 0 , 2 , 3 , 1 ''right
  quad 7 , 6 , 4 , 5 ''left
  quad 0 , 4 , 5 , 1 ''up
  quad 7 , 3 , 2 , 6 ''down
  quad 0 , 4 , 6 , 2 ''back
  quad 7 , 5 , 1 , 3 ''front
end sub
sub cilinder( sides as integer , dx as single , dy as single )
  dim f as single
  if sides < 3 then sides = 3
  if sides > 64 then sides = 64
  for f = 0 to sides + 2
    setpoint f , box.m.x + sin( f * pi * 2 / sides ) * box.d.x _
               , box.m.y - box.d.y _
               , box.m.z + cos( f * pi * 2 / sides ) * box.d.z
    setpoint f + sides + 1 , box.m.x + sin( f * pi * 2 / sides ) * dx _
                           , box.m.y + box.d.y _
                           , box.m.z + cos( f * pi * 2 / sides ) * dy
  next f
  for f = 0 to sides + 1
    quad f , f + 1 , f + 2 + sides , f + 1 + sides 
  next f
    setpoint 255 , 0 , box.m.y + box.d.y , 0
    for f = 0 to sides
        setpoint f , box.m.x + sin( f * pi * 2 / sides ) * dx _
               , box.m.y + box.d.y _
               , box.m.z + cos( f * pi * 2 / sides ) * dy  
    next f
    for f = 0 to sides
      tri 255 , f , f + 1 
    next f
    setpoint 255 , 0 , box.m.y - box.d.y , 0
    for f = 0 to sides + 2
        setpoint f , box.m.x - sin( f * pi * 2 / sides ) * box.d.x _
               , box.m.y - box.d.y _
               , box.m.z + cos( f * pi * 2 / sides ) * box.d.z  
    next f
    for f = 0 to sides + 2
      tri 255 , f , f + 1 
    next f
end sub

type tSphere
  dim as t3d center
  dim as tmaterial mat
  dim as double radius , radius2
  dim as integer matrixnumber
  declare sub fill( c as t3d , r as double )
  declare function hit( o as t3d , d as t3d ) as double 
  declare function normal( nu as t3d ) as t3d
end type
sub tSphere.fill( c as t3d , r as double )
  spot c.x , c.y , c.z
  center = c
  radius = r
  radius2 = r * r
  mat = material
  matrixnumber = number
end sub
function tSphere.hit( o as t3d , d as t3d ) as double
  dim as double t , a , b , c , disc
  dim as t3d temp = o - center
  a = dot( d , d )
  b = 2 * dot( temp , d )
  c = dot( temp , temp ) - radius2
  disc = b ^ 2 - 4 * a * c
  if disc < 0 then 
    return -1
  else
    dim as double e = sqr( disc ) 
    dim as double demon = 2 * a
    t = ( -b - e ) / demon
    if t > 1e-12 then
      return t
    end if
    
    t = ( -b + e ) / demon
    if t > 1e-12 then 
      return t
    end if
  end if
  return -1
end function
function tSphere.normal( nu as t3d ) as t3d
  return nu - center
end function
dim shared as tSphere spheres( 1000 )
dim shared as integer spheretel
sub sphere2( c as t3d , r as double )
  spheres( spheretel ).fill c , r 
  spheretel += 1
end sub
sub sphere( a as double , b as double , c as double _
  , r as double , kl as t3d )
  material.kl( 0 ) = kl
  material.klmax = 0
  material.mattype = 0
  spheres( spheretel ).fill t3d( a , b , c ) , r
  spheretel += 1
end sub
function mirror( d as t3d , q as t3d ) as t3d
  dim as double ha , hb
  ha = atan2( q.y , q.z ) * 180 / pi
  rotate q.y , q.z , -ha 
  rotate d.y , d.z , -ha 
  hb = atan2( q.x , q.z ) * 180 / pi
  rotate q.x , q.z , -hb 
  rotate d.x , d.z , -hb
  d.z *= -1
  rotate d.x , d.z , hb 
  rotate d.y , d.z , ha 
  return d
end function
dim shared as t3d light
light.fill -1 , 3 , 1
type t_fog
  dim as t3d kl
  dim as double dist , height
  dim as integer visable
end type
dim shared as t_fog fog
const as integer mat_plane = 0
const as integer mat_wood = 1
const as integer mat_marble = 2
const as integer mat_turb = 3
const as integer mat_gradient = 5

function texture( x as double , y as double , z as double _
  , m as integer , t as double , i as integer ) as double
  dim as t3d s
  dim as double turb = 0
  if t > 0 then turb = turbulence3d(x,y,z,i)*t
  s = material.scale
  x /= s.x
  y /= s.y
  z /= s.z
  select case m
    case mat_turb
      return turb
    case mat_marble
      return sin( y + turb ) / 2 + .5 
    case mat_wood
      return sin( sqr( x * x + z * z ) + turb ) / 2 + .5
    case mat_gradient
      y += turb
      return y - int( y )
    case else
      return 0.0
  end select
end function
dim shared as t3d black , red , green , yellow , blue _
, magenta , cyan , white , gray , pink , orange
black.fill   0  , 0  , 0
red.fill     1  , 0  , 0
green.fill   0  , 1  , 0
yellow.fill  1  , 1  , 0
blue.fill    0  , 0  , 1
magenta.fill 1  , 0  , 1
cyan.fill    0  , 1  , 1
white.fill   1  , 1  , 1
gray.fill    .5 , .5 , .5
pink.fill    1  , .5 , .5
orange.fill  1  , .5 , 0
function renderPixel( o as t3d , d as t3d _
  , dept as integer ) as t3d
  dim as integer i , id = -1 , id2 = -1 
  dim as double dist , tridist = 1e9 , sphdist = 1e9 , a 
  dim as t3d kl1 , kl2 , q , p , shade , uit
  dim as double reflection , dd
  for i = 0 to tritel
    dist = triangles( i ).hit( o , d )
    if dist > 0 andalso dist < tridist then
      id = i
      tridist = dist
    end if
  next i
  for i = 0 to spheretel
    dist = spheres( i ).hit( o , d )
    if dist > 0 andalso dist < sphdist then
      id2 = i
      sphdist = dist
    end if
  next i
  if tridist = 1e9 and sphdist = 1e9 then
    if fog.visable then
      return fog.kl
    else
      return t3d()
    end if
  end if
  if id = -1 and id2 = -1 then return blue
  if tridist < sphdist then 
    reflection = triangles( id ).mat.reflection
    kl1 = triangles( id ).mat.kl( 0 )
    a = angle( triangles( id ).n , light )
    kl1 = kl1 * ( cos( a ) / 2 + 0.5 )
    p = o + d * tridist
    if fog.visable then
      kl1 = t3dmix( kl1 , tridist / 10 , fog.kl )
    end if
    return kl1
  else
    reflection = spheres( id2 ).mat.reflection
    p = o + d * sphdist
    q = spheres( id2 ).normal( p )
    p = q
    q = normalize(q)
    a = angle( q , light )
    i = spheres( id2 ).mat.klmax
    if i >= 1 then
      lokal p.x , p.y , p.z
      dd = texture( p.x + spheres( id2 ).radius _
      , p.y + spheres( id2 ).radius _
      , p.z + spheres( id2 ).radius _
      , spheres( id2 ).mat.mattype _
      , spheres( id2 ).mat.turbulence _
      , spheres( id2 ).mat.waves )
      i = int( i * dd )
      kl1 = spheres( id2 ).mat.kl( i )
      kl2 = spheres( id2 ).mat.kl( i + 1 )
      kl1 = t3dmix( kl1 , dd , kl2 ) 
    end if
    if spheres( id2 ).mat.shadow  then
      kl1 = kl1 * ( cos( a ) / 2 + 0.5 )
    end if
    if fog.visable then
      kl1 = t3dmix( kl1 , sphdist / 10 , fog.kl )
    end if
    if reflection < 0.001 or dept < 0 then
      return kl1
    else
      d = mirror( d , q )
      kl2 = renderPixel( p , d , dept - 1 )
      return kl1 + ( kl2 - kl1 ) * reflection
    end if
  end if
  if fog.visable then return fog.kl
  return red
end function

const as integer arm   = 1
const as integer elbow = 2
const as integer wrist = 3
const as integer leg   = 4
const as integer knee  = 5
const as integer enkle = 6
const as integer neck  = 7
const as integer eye   = 8
const as integer wenk  = 9
const as integer tail  = 10
const as integer thumb = 11
const as integer index = 14
const as integer midle = 17
const as integer ring  = 20
const as integer lr    = 32

Sub Kop( qq as integer , kl as t3d )
    link 15, 0, 0, 0, 0, 0, 0,xyz, number
        sphere 0, 0, 0, 30, kl
    If qq = 1 Then
        sphere 25, 25, 0, 9, kl
        sphere -25, 25, 0, 9, kl
        sphere 0, 0, -40, 12, gray
    Else
        sphere 30, 0, 0, 9, kl
        sphere -30, 0, 0, 9, kl
        sphere 0, 0, -40, 12, kl
    End If
        child 16, 14, 14, -14, eye ,xyz, 15
          sphere 0, 0, 0, 13, white
          sphere 0, 0, -10, 7, black
        child 16, -14, 14, -14, eye + lr,xyz, 15
          sphere 0, 0, 0, 13, white
          sphere 0, 0, -10, 7, black
End Sub


sub man( trui as t3d , broek as t3d )
    link 9 , 0,0,0 , 0,0,0 , xyz , number
        sphere 0, 50, 0, 30, trui
        sphere 0, 25, 0, 23, broek
        sphere 0, 0, 0, 15, broek
    child 11, 0, 70, 0, neck, xyz, 9
    child 12, 0, 30, 0, neck+lr, xyz, 11
        Kop 0, pink
    child 11, 20, -10, 0, leg, yzx, 9
        sphere 0, 0, 0, 16, broek
        sphere 0, -20, 0, 16, broek
    child 12, 0, -40, 0, knee, xyz, 11
        sphere 0, 0, 0, 16, broek
        sphere 0, -20, 0, 16, broek
    child 13, 0, -40, 0, enkle, xzy, 12
        sphere 0, 0, 0, 12, gray
        sphere 0, 0, -20, 12, gray
    child 11, -20, -10, 0, leg+lr , yzx, 9
        sphere 0, 0, 0, 16, broek
        sphere 0, -20, 0, 16, broek
    child 12, 0, -40, 0, knee+lr, xyz, 11
        sphere 0, 0, 0, 16, broek
        sphere 0, -20, 0,16, broek
    child 13, 0, -40, 0,enkle+lr, xzy, 12
        sphere 0, 0, 0, 12, gray
        sphere 0, 0, -20, 12, gray
    child 11, 40, 60, 0, arm, xzy, 9
        sphere 0, 0, 0, 16, trui
        sphere 6, -20, 0, 12, trui
    child 12, 6, -40, 0, elbow, xyz, 11
        sphere 0, 0, 0, 12, trui
        sphere 0, -20, 0, 12, trui
        sphere 0, -42, 0, 8, pink
    child 11, -40, 60, 0, arm+lr, xzy, 9
        sphere 0, 0, 0, 16, trui
        sphere -6, -20, 0, 12, trui
    child 12, -6, -40, 0, elbow+lr, xyz, 11
        sphere 0, 0, 0, 12, trui
        sphere 0, -20, 0, 12, trui
        sphere 0, -42, 0, 8, pink
end sub
sub man_walk( f as double , a as double )
    skelet arm , pend( f , a ) , 0 , 0
    skelet elbow , -abs( a ) , 0 , 0
    skelet arm + lr , pend( f + 180, a ) , 0 , 0
    skelet elbow + lr , -abs( a ) , 0 , 0
    skelet leg , pend( f + 180 , a ) , 0 , 0
    skelet knee , pend( f + 90 , a ) + a , 0 , 0
    skelet leg + lr , pend( f , a ) , 0 , 0
    skelet knee + lr , pend( f - 90 , a ) + a , 0 , 0
end sub
sub dog_walk( f as double , a as double )
    skelet arm , pend( f , a ) , 0 , 0
    skelet elbow , pend( f - 90 , a ) + a , 0 , 0
    skelet arm + lr , pend( f + 180, a ) , 0 , 0
    skelet elbow + lr , pend( f + 90 , a ) + a , 0 , 0
    skelet leg , pend( f + 180 , a ) , 0 , 0
    skelet knee , pend( f + 90 , a ) + a , 0 , 0
    skelet leg + lr , pend( f , a ) , 0 , 0
    skelet knee + lr , pend( f - 90 , a ) + a , 0 , 0
    skelet tail , -a , pend( f * 2 , a ) , 0
end sub

sub pilko( kl as t3d )
  sphere 0,0,0,30 , kl
  sphere 0,0,50,30 , kl
  child 2 , 0,20,-20 , neck , xyz , 1
    child 3 , 0,20,-20 , neck , zyx , 2
      kop 1 , kl
  child 11, -20, -10, 50, leg, yzx, 1
    sphere 0, 0, 0, 16, kl
    sphere 0, -20, 0, 16, kl
    child 12, 0, -40, 0, knee, xyz, 11
      sphere 0, 0, 0, 16, kl
      sphere 0, -20, 0, 16, kl
      child 13, 0, -40, 0, enkle, xzy, 12
        sphere 0, 0, 0, 12, kl
        sphere 0, 0, -20, 12, kl
  child 11, 20, -10, 50, leg+lr, yzx, 1
    sphere 0, 0, 0, 16, kl
    sphere 0, -20, 0, 16, kl
    child 12, 0, -40, 0, knee+lr, xyz, 11
      sphere 0, 0, 0, 16, kl
      sphere 0, -20, 0, 16, kl
      child 13, 0, -40, 0, enkle+lr, xzy, 12
        sphere 0, 0, 0, 12, kl
        sphere 0, 0, -20, 12, kl
  child 11, 20, -10, 0, arm, yzx, 1
    sphere 0, 0, 0, 16, kl
    sphere 0, -20, 0, 16, kl
    child 12, 0, -40, 0, elbow, xyz, 11
      sphere 0, 0, 0, 16, kl
      sphere 0, -20, 0, 16, kl
      child 13, 0, -40, 0, wrist, xzy, 12
        sphere 0, 0, 0, 12, kl
        sphere 0, 0, -20, 12, kl
  child 11, -20, -10, 0, arm+lr, yzx, 1
    sphere 0, 0, 0, 16, kl
    sphere 0, -20, 0, 16, kl
    child 12, 0, -40, 0, elbow+lr, xyz, 11
      sphere 0, 0, 0, 16, kl
      sphere 0, -20, 0, 16, kl
      child 13, 0, -40, 0, wrist+lr, xzy, 12
        sphere 0, 0, 0, 12, kl
        sphere 0, 0, -20, 12, kl
  child 3 , 0,14,90 , tail , xyz , 2
    dim i as integer
    for i = 0 to 5
      sphere 0,i*8,0,10 , kl
    next i
end sub
sub saveframe( f as string , no as integer , m as integer )
  bsave f + nr( no , m ) + ".bmp" , 0
end sub
sub draw_all()
  dim as double x , y
  dim as t3d o , d
  paint( 1 , 1 ) , rgb( 255 , 255 , 255 )
  for x = -winx / 2 to winx / 2
    for y = -winy / 2 to winy / 2
      o.fill 0 , 0 , 1000
      d.fill x , y , -1000
      pset( x + winx / 2 , winy / 2 - y ) _
      , renderPixel( o , d , 7 ).toColor
    next y
  next x
end sub
'' and finaly draw somthing
'' reset world
tritel = 0
spheretel = 0

'' make world here under

'' instructions :
'' there are 10 kl
material.kl(0) = blue 
material.kl(1) = yellow
material.kl(2) = green
material.kl(3) = orange
material.kl(4) = gray
material.kl(5) = white
material.klmax = 5
'' DON'T DO : scale.fill 0,0,0
material.scale.fill 100,100,100
'' make waves not to big !! wil slow things
material.waves = 127
material.turbulence = 10
'' mattype = mat_plane , mat_marble , mat_gradient , mat_wood
material.mattype = mat_marble
sphere2 t3d( -100 , 0 , 0 ) , 300

fog.visable = 0
fog.kl = gray
fog.dist = 10

draw_all

bsave "texture-test.bmp" , 0
print "ready"
sleep
screen 0
bluatigro
Posts: 660
Joined: Apr 25, 2012 10:35
Location: netherlands

Re: raytrace try

Post by bluatigro »

update :
try at color gradiënt

error :
line 390 : type error

Code: Select all

''bluatigro 1 dec  2015
''triangle | sphere - ray

#include "t_3d.bas"
#include "basis_3d_m.bas"
#include "noise.bas"


DIM shared AS INTEGeR winx, winy, bitdepth
screen 20 , 32
SCREENINFO winx , winy , bitdepth

dim shared as t3d pnt( 256 )
sub setpoint( no as integer , a as double _
  , b as double , c as double )
  if no < 0 or no > ubound( pnt ) then exit sub
  spot a , b , c
  pnt( no ).x = a
  pnt( no ).y = b
  pnt( no ).z = c
end sub
type tmaterial
  dim as t3d kl( 10 ) , scale , translate
  dim as double reflection , turbulence
  dim as integer mattype , klmax , shadow , waves
  declare constructor()
end type
constructor tmaterial()
  scale.fill 1,1,1
  shadow = 1
  waves = 7
end constructor
dim shared as tmaterial material
type triangle
public :
  dim as t3d punt( 2 ) , n , led 
  dim as tmaterial mat
  declare sub fill( p1 as integer , p2 as integer _
  , p3 as integer )
  declare function hit( o as t3d , d as t3d ) as double
end type
sub triangle.fill( p1 as integer , p2 as integer _
  , p3 as integer )
  if p1 < 0 or p1 > ubound( pnt ) then exit sub
  if p2 < 0 or p2 > ubound( pnt ) then exit sub
  if p3 < 0 or p3 > ubound( pnt ) then exit sub
  punt( 0 ) = pnt( p1 )
  punt( 1 ) = pnt( p2 )
  punt( 2 ) = pnt( p3 )
  led = ( punt( 0 ) + punt( 1 ) + punt( 2 ) ) / 3
  n = ( punt( 2 ) - punt( 0 ) ) \ ( punt( 1 ) - punt( 0 ) )
  n *= -1
  n = normalize( n )
  mat = material
end sub
function triangle.hit( o as t3d , d as t3d ) as double
  dim as t3d e1 = punt( 1 ) - punt( 0 )
  dim as t3d e2 = punt( 2 ) - punt( 0 )
  dim as t3d p = d \ e2
  dim as double a = dot( e1 , p )
  if abs( a ) < 1e-9 then return -1
  dim as double f = 1 / a
  dim as t3d s = o - punt( 0 )
  dim as double u = f * dot( s , p )
  if u < 0 or u > 1 then return -1
  dim as t3d q = s \ e1
  dim as double v = f * dot( d , q )
  if v < 0 or u + v > 1 then return -1
  return f * dot( e2 , q )
end function

dim shared as triangle triangles( 1000 )
dim shared as integer tritel = 0
sub tri( p1 as integer , p2 as integer _
  , p3 as integer )
  triangles( tritel ).fill p1 , p2 , p3
  tritel += 1
end sub
sub quad( p1 as integer , p2 as integer _
  , p3 as integer , p4 as integer )
  tri p1 , p2 , p3 
  tri p1 , p3 , p4
end sub
type Tbox
  m as t3d
  d as t3d
end type
dim shared box as Tbox
sub setbox( mx as double , my as double _
  , mz as double , dx as double _
  , dy as double , dz as double )
  box.m.x = mx
  box.m.y = my
  box.m.z = mz
  box.d.x = dx
  box.d.y = dy
  box.d.z = dz
end sub
sub torus( a as integer , b as integer )
  dim i as double , j as double , i2 as double , j2 as double
  if a < 3 then a = 3 
  if a > 64 then a = 64
  if b < 3 then b = 3 
  if b > 64 then b = 64 
  dim mx as double , my as double , mz as double , dx as double , dy as double , dz as double 
  mx = box.m.x 
  my = box.m.y 
  mz = box.m.z 
  dx = box.d.x 
  dy = box.d.y 
  dz = box.d.z 
  for i = -PI to PI  step PI / a * 2 
    i2 = i + PI / a * 2 
    for j = -PI to PI step PI / b * 2 
      j2 = j + PI / b * 2 
      setpoint 0 _ 
      , mx + ( dx + dy * cos( i ) ) * cos( j ) _
      , my + ( dx + dy * cos( i ) ) * sin( j ) _
      , mz + sin( i ) * dz  
      setpoint 1 _
      , mx + ( dx + dy * cos( i ) ) * cos( j2 ) _
      , my + ( dx + dy * cos( i ) ) * sin( j2 ) _
      , mz + sin( i ) * dz 
      setpoint 2 _
      , mx + ( dx + dy * cos( i2 ) ) * cos( j2 ) _
      , my + ( dx + dy * cos( i2 ) ) * sin( j2 ) _
      , mz + sin( i2 ) * dz 
      setpoint 3 _ 
      , mx + ( dx + dy * cos( i2 ) ) * cos( j ) _
      , my + ( dx + dy * cos( i2 ) ) * sin( j ) _
      , mz + sin( i2 ) * dz 
      quad 0 , 1 , 2 , 3 
    next j
  next i
end sub
sub cube()
  setpoint 0 , box.m.x + box.d.x , box.m.y + box.d.y , box.m.z + box.d.z
  setpoint 1 , box.m.x + box.d.x , box.m.y + box.d.y , box.m.z - box.d.z
  setpoint 2 , box.m.x + box.d.x , box.m.y - box.d.y , box.m.z + box.d.z
  setpoint 3 , box.m.x + box.d.x , box.m.y - box.d.y , box.m.z - box.d.z
  setpoint 4 , box.m.x - box.d.x , box.m.y + box.d.y , box.m.z + box.d.z
  setpoint 5 , box.m.x - box.d.x , box.m.y + box.d.y , box.m.z - box.d.z
  setpoint 6 , box.m.x - box.d.x , box.m.y - box.d.y , box.m.z + box.d.z
  setpoint 7 , box.m.x - box.d.x , box.m.y - box.d.y , box.m.z - box.d.z
  quad 0 , 2 , 3 , 1 ''right
  quad 7 , 6 , 4 , 5 ''left
  quad 0 , 4 , 5 , 1 ''up
  quad 7 , 3 , 2 , 6 ''down
  quad 0 , 4 , 6 , 2 ''back
  quad 7 , 5 , 1 , 3 ''front
end sub
sub cilinder( sides as integer , dx as single , dy as single )
  dim f as single
  if sides < 3 then sides = 3
  if sides > 64 then sides = 64
  for f = 0 to sides + 2
    setpoint f , box.m.x + sin( f * pi * 2 / sides ) * box.d.x _
               , box.m.y - box.d.y _
               , box.m.z + cos( f * pi * 2 / sides ) * box.d.z
    setpoint f + sides + 1 , box.m.x + sin( f * pi * 2 / sides ) * dx _
                           , box.m.y + box.d.y _
                           , box.m.z + cos( f * pi * 2 / sides ) * dy
  next f
  for f = 0 to sides + 1
    quad f , f + 1 , f + 2 + sides , f + 1 + sides 
  next f
    setpoint 255 , 0 , box.m.y + box.d.y , 0
    for f = 0 to sides
        setpoint f , box.m.x + sin( f * pi * 2 / sides ) * dx _
               , box.m.y + box.d.y _
               , box.m.z + cos( f * pi * 2 / sides ) * dy  
    next f
    for f = 0 to sides
      tri 255 , f , f + 1 
    next f
    setpoint 255 , 0 , box.m.y - box.d.y , 0
    for f = 0 to sides + 2
        setpoint f , box.m.x - sin( f * pi * 2 / sides ) * box.d.x _
               , box.m.y - box.d.y _
               , box.m.z + cos( f * pi * 2 / sides ) * box.d.z  
    next f
    for f = 0 to sides + 2
      tri 255 , f , f + 1 
    next f
end sub

type tSphere
  dim as t3d center
  dim as tmaterial mat
  dim as double radius , radius2
  dim as integer matrixnumber
  declare sub fill( c as t3d , r as double )
  declare function hit( o as t3d , d as t3d ) as double 
  declare function normal( nu as t3d ) as t3d
end type
sub tSphere.fill( c as t3d , r as double )
  spot c.x , c.y , c.z
  center = c
  radius = r
  radius2 = r * r
  mat = material
  matrixnumber = number
end sub
function tSphere.hit( o as t3d , d as t3d ) as double
  dim as double t , a , b , c , disc
  dim as t3d temp = o - center
  a = dot( d , d )
  b = 2 * dot( temp , d )
  c = dot( temp , temp ) - radius2
  disc = b ^ 2 - 4 * a * c
  if disc < 0 then 
    return -1
  else
    dim as double e = sqr( disc ) 
    dim as double demon = 2 * a
    t = ( -b - e ) / demon
    if t > 1e-12 then
      return t
    end if
    
    t = ( -b + e ) / demon
    if t > 1e-12 then 
      return t
    end if
  end if
  return -1
end function
function tSphere.normal( nu as t3d ) as t3d
  return nu - center
end function
dim shared as tSphere spheres( 1000 )
dim shared as integer spheretel
sub sphere2( c as t3d , r as double )
  spheres( spheretel ).fill c , r 
  spheretel += 1
end sub
sub sphere( a as double , b as double , c as double _
  , r as double , kl as t3d )
  material.kl( 0 ) = kl
  material.klmax = 0
  material.mattype = 0
  spheres( spheretel ).fill t3d( a , b , c ) , r
  spheretel += 1
end sub
function mirror( d as t3d , q as t3d ) as t3d
  dim as double ha , hb
  ha = atan2( q.y , q.z ) * 180 / pi
  rotate q.y , q.z , -ha 
  rotate d.y , d.z , -ha 
  hb = atan2( q.x , q.z ) * 180 / pi
  rotate q.x , q.z , -hb 
  rotate d.x , d.z , -hb
  d.z *= -1
  rotate d.x , d.z , hb 
  rotate d.y , d.z , ha 
  return d
end function
dim shared as t3d light
light.fill -1 , 3 , 1
type t_fog
  dim as t3d kl
  dim as double dist , height
  dim as integer visable
end type
dim shared as t_fog fog
const as integer mat_plane = 0
const as integer mat_wood = 1
const as integer mat_marble = 2
const as integer mat_turb = 3
const as integer mat_gradient = 5

function texture( x as double , y as double , z as double _
  ,  mat as tmaterial ) as double
  dim as t3d s = mat.scale
  dim as integer i = mat.waves 
  dim as double t = mat.turbulence
  x /= s.x
  y /= s.y
  z /= s.z
  select case mat.mattype
    case mat_turb
      return turbulence3d(x,y,z,i)
    case mat_marble
      return sin(y+turbulence3d(x,y,z,i)*t) / 2 + .5 
    case mat_wood
      return sin(sqr(x*x+z*z)+turbulence3d(x,y,z,i)*t) / 2 + .5
    case mat_gradient
      y += turbulence3d(x,y,z,i)*t
      return y - int( y )
    case else
      return 0.0
  end select
end function

function texture2( x as double , y as double , z as double _
  , mat as integer , t as double , i as integer ) as double
  dim as t3d s
  dim as double turb = 0
    x /= s.x
    y /= s.y
    z /= s.z
  if mat <> mat_plane and t > 0 then 
    turb = turbulence3d(x,y,z,i)*t
  end if
  select case mat
    case mat_turb
      return turb
    case mat_marble
      return sin( y + turb ) / 2 + .5 
    case mat_wood
      return sin( sqr( x * x + z * z ) + turb ) / 2 + .5
    case mat_gradient
      y += turb
      return y - int( y )
    case else
      return 0.0
  end select
end function
dim shared as t3d black , red , green , yellow , blue _
, magenta , cyan , white , gray , pink , orange
black.fill   0  , 0  , 0
red.fill     1  , 0  , 0
green.fill   0  , 1  , 0
yellow.fill  1  , 1  , 0
blue.fill    0  , 0  , 1
magenta.fill 1  , 0  , 1
cyan.fill    0  , 1  , 1
white.fill   1  , 1  , 1
gray.fill    .5 , .5 , .5
pink.fill    1  , .5 , .5
orange.fill  1  , .5 , 0
function between( low as double _
  , f as double , high as double ) as integer
  return ( low  < f ) and ( f < high )
end function
function renderPixel( o as t3d , d as t3d _
  , dept as integer ) as t3d
  dim as integer i , id = -1 , id2 = -1 
  dim as double dist , tridist = 1e9 , sphdist = 1e9 , a 
  dim as t3d kl1 , kl2 , q , p , shade , uit
  dim as double reflection , dd
  for i = 0 to tritel
    dist = triangles( i ).hit( o , d )
    if dist > 0 andalso dist < tridist then
      id = i
      tridist = dist
    end if
  next i
  for i = 0 to spheretel
    dist = spheres( i ).hit( o , d )
    if dist > 0 andalso dist < sphdist then
      id2 = i
      sphdist = dist
    end if
  next i
  if tridist = 1e9 and sphdist = 1e9 then
    if fog.visable then
      return fog.kl
    else
      return t3d()
    end if
  end if
  if id = -1 and id2 = -1 then return blue
  if tridist < sphdist then 
    reflection = triangles( id ).mat.reflection
    kl1 = triangles( id ).mat.kl( 0 )
    a = angle( triangles( id ).n , light )
    kl1 = kl1 * ( cos( a ) / 2 + 0.5 )
    p = o + d * tridist
    if fog.visable then
      kl1 = t3dmix( kl1 , tridist / 10 , fog.kl )
    end if
    return kl1
  else
    reflection = spheres( id2 ).mat.reflection
    p = o + d * sphdist
    q = spheres( id2 ).normal( p )
    p = q
    q = normalize(q)
    a = angle( q , light )
    i = spheres( id2 ).mat.klmax
    if i >= 1 then
      lokal p.x , p.y , p.z
      dd = texture( p.x + spheres( id2 ).radius _
      , p.y + spheres( id2 ).radius _
      , p.z + spheres( id2 ).radius _
      , spheres( id2 ).mat )
      dim as integer t , fl = 1
      while fl
        if between(cdbl(t),i*d,cdbl(t+1)) then
          kl1 = spheres( id2 ).mat.kl( t )
          kl2 = spheres( id2 ).mat.kl( t + 1 )
          kl1 = t3dmix( kl1 , dd , kl2 ) 
          fl = 0
          t += 1
        end if
      wend
    end if
    if spheres( id2 ).mat.shadow  then
      kl1 = kl1 * ( cos( a ) / 2 + 0.5 )
    end if
    if fog.visable then
      kl1 = t3dmix( kl1 , sphdist / 10 , fog.kl )
    end if
    if reflection < 0.001 or dept < 0 then
      return kl1
    else
      d = mirror( d , q )
      kl2 = renderPixel( p , d , dept - 1 )
      return kl1 + ( kl2 - kl1 ) * reflection
    end if
  end if
  if fog.visable then return fog.kl
  return red
end function

const as integer arm   = 1
const as integer elbow = 2
const as integer wrist = 3
const as integer leg   = 4
const as integer knee  = 5
const as integer enkle = 6
const as integer neck  = 7
const as integer eye   = 8
const as integer wenk  = 9
const as integer tail  = 10
const as integer thumb = 11
const as integer index = 14
const as integer midle = 17
const as integer ring  = 20
const as integer lr    = 32

Sub Kop( qq as integer , kl as t3d )
    link 15, 0, 0, 0, 0, 0, 0,xyz, number
        sphere 0, 0, 0, 30, kl
    If qq = 1 Then
        sphere 25, 25, 0, 9, kl
        sphere -25, 25, 0, 9, kl
        sphere 0, 0, -40, 12, gray
    Else
        sphere 30, 0, 0, 9, kl
        sphere -30, 0, 0, 9, kl
        sphere 0, 0, -40, 12, kl
    End If
        child 16, 14, 14, -14, eye ,xyz, 15
          sphere 0, 0, 0, 13, white
          sphere 0, 0, -10, 7, black
        child 16, -14, 14, -14, eye + lr,xyz, 15
          sphere 0, 0, 0, 13, white
          sphere 0, 0, -10, 7, black
End Sub

sub man( trui as t3d , broek as t3d )
    link 9 , 0,0,0 , 0,0,0 , xyz , number
        sphere 0, 50, 0, 30, trui
        sphere 0, 25, 0, 23, broek
        sphere 0, 0, 0, 15, broek
    child 11, 0, 70, 0, neck, xyz, 9
    child 12, 0, 30, 0, neck+lr, xyz, 11
        Kop 0, pink
    child 11, 20, -10, 0, leg, yzx, 9
        sphere 0, 0, 0, 16, broek
        sphere 0, -20, 0, 16, broek
    child 12, 0, -40, 0, knee, xyz, 11
        sphere 0, 0, 0, 16, broek
        sphere 0, -20, 0, 16, broek
    child 13, 0, -40, 0, enkle, xzy, 12
        sphere 0, 0, 0, 12, gray
        sphere 0, 0, -20, 12, gray
    child 11, -20, -10, 0, leg+lr , yzx, 9
        sphere 0, 0, 0, 16, broek
        sphere 0, -20, 0, 16, broek
    child 12, 0, -40, 0, knee+lr, xyz, 11
        sphere 0, 0, 0, 16, broek
        sphere 0, -20, 0,16, broek
    child 13, 0, -40, 0,enkle+lr, xzy, 12
        sphere 0, 0, 0, 12, gray
        sphere 0, 0, -20, 12, gray
    child 11, 40, 60, 0, arm, xzy, 9
        sphere 0, 0, 0, 16, trui
        sphere 6, -20, 0, 12, trui
    child 12, 6, -40, 0, elbow, xyz, 11
        sphere 0, 0, 0, 12, trui
        sphere 0, -20, 0, 12, trui
        sphere 0, -42, 0, 8, pink
    child 11, -40, 60, 0, arm+lr, xzy, 9
        sphere 0, 0, 0, 16, trui
        sphere -6, -20, 0, 12, trui
    child 12, -6, -40, 0, elbow+lr, xyz, 11
        sphere 0, 0, 0, 12, trui
        sphere 0, -20, 0, 12, trui
        sphere 0, -42, 0, 8, pink
end sub
sub man_walk( f as double , a as double )
    skelet arm , pend( f , a ) , 0 , 0
    skelet elbow , -abs( a ) , 0 , 0
    skelet arm + lr , pend( f + 180, a ) , 0 , 0
    skelet elbow + lr , -abs( a ) , 0 , 0
    skelet leg , pend( f + 180 , a ) , 0 , 0
    skelet knee , pend( f + 90 , a ) + a , 0 , 0
    skelet leg + lr , pend( f , a ) , 0 , 0
    skelet knee + lr , pend( f - 90 , a ) + a , 0 , 0
end sub
sub dog_walk( f as double , a as double )
    skelet arm , pend( f , a ) , 0 , 0
    skelet elbow , pend( f - 90 , a ) + a , 0 , 0
    skelet arm + lr , pend( f + 180, a ) , 0 , 0
    skelet elbow + lr , pend( f + 90 , a ) + a , 0 , 0
    skelet leg , pend( f + 180 , a ) , 0 , 0
    skelet knee , pend( f + 90 , a ) + a , 0 , 0
    skelet leg + lr , pend( f , a ) , 0 , 0
    skelet knee + lr , pend( f - 90 , a ) + a , 0 , 0
    skelet tail , -a , pend( f * 2 , a ) , 0
end sub

sub pilko( kl as t3d )
  sphere 0,0,0,30 , kl
  sphere 0,0,50,30 , kl
  child 2 , 0,20,-20 , neck , xyz , 1
    child 3 , 0,20,-20 , neck , zyx , 2
      kop 1 , kl
  child 11, -20, -10, 50, leg, yzx, 1
    sphere 0, 0, 0, 16, kl
    sphere 0, -20, 0, 16, kl
    child 12, 0, -40, 0, knee, xyz, 11
      sphere 0, 0, 0, 16, kl
      sphere 0, -20, 0, 16, kl
      child 13, 0, -40, 0, enkle, xzy, 12
        sphere 0, 0, 0, 12, kl
        sphere 0, 0, -20, 12, kl
  child 11, 20, -10, 50, leg+lr, yzx, 1
    sphere 0, 0, 0, 16, kl
    sphere 0, -20, 0, 16, kl
    child 12, 0, -40, 0, knee+lr, xyz, 11
      sphere 0, 0, 0, 16, kl
      sphere 0, -20, 0, 16, kl
      child 13, 0, -40, 0, enkle+lr, xzy, 12
        sphere 0, 0, 0, 12, kl
        sphere 0, 0, -20, 12, kl
  child 11, 20, -10, 0, arm, yzx, 1
    sphere 0, 0, 0, 16, kl
    sphere 0, -20, 0, 16, kl
    child 12, 0, -40, 0, elbow, xyz, 11
      sphere 0, 0, 0, 16, kl
      sphere 0, -20, 0, 16, kl
      child 13, 0, -40, 0, wrist, xzy, 12
        sphere 0, 0, 0, 12, kl
        sphere 0, 0, -20, 12, kl
  child 11, -20, -10, 0, arm+lr, yzx, 1
    sphere 0, 0, 0, 16, kl
    sphere 0, -20, 0, 16, kl
    child 12, 0, -40, 0, elbow+lr, xyz, 11
      sphere 0, 0, 0, 16, kl
      sphere 0, -20, 0, 16, kl
      child 13, 0, -40, 0, wrist+lr, xzy, 12
        sphere 0, 0, 0, 12, kl
        sphere 0, 0, -20, 12, kl
  child 3 , 0,14,90 , tail , xyz , 2
    dim i as integer
    for i = 0 to 5
      sphere 0,i*8,0,10 , kl
    next i
end sub
sub saveframe( f as string , no as integer , m as integer )
  bsave f + nr( no , m ) + ".bmp" , 0
end sub
sub draw_all()
  dim as double x , y
  dim as t3d o , d
  paint( 1 , 1 ) , rgb( 255 , 255 , 255 )
  for x = -winx / 2 to winx / 2
    for y = -winy / 2 to winy / 2
      o.fill 0 , 0 , 1000
      d.fill x , y , -1000
      pset( x + winx / 2 , winy / 2 - y ) _
      , renderPixel( o , d , 7 ).toColor
    next y
  next x
end sub
'' and finaly draw somthing
'' reset world
tritel = 0
spheretel = 0

'' make world here under

'' instructions :
'' there are 10 kl
material.kl(0) = blue 
material.kl(1) = yellow
material.kl(2) = green
material.kl(3) = orange
material.kl(4) = gray
material.kl(5) = white
material.klmax = 5
'' DON'T DO : scale.fill 0,0,0
material.scale.fill 100,100,100
'' make waves not to big !! wil slow things
material.waves = 127
material.turbulence = 10
'' mattype :
'' mat_plane , mat_marble , mat_gradient , mat_wood , mat_turb
material.mattype = mat_marble
sphere2 t3d( -300 , 0 , 0 ) , 300
'' instructions :
'' there are 10 kl
material.kl(0) = black
material.kl(1) = gray
material.kl(2) = white
material.klmax = 2
'' DON'T DO : scale.fill 0,0,0
material.scale.fill 10,10,10
'' make waves not to big !! wil slow things
material.waves = 127
material.turbulence = 100
'' mattype :
'' mat_plane , mat_marble , mat_gradient , mat_wood , mat_turb
material.mattype = mat_wood
''sphere2 t3d( 300 , 0 , 0 ) , 300

fog.visable = 0
fog.kl = gray
fog.dist = 10

draw_all

''bsave "texture-test.bmp" , 0
print "ready"
sleep
screen 0
bluatigro
Posts: 660
Joined: Apr 25, 2012 10:35
Location: netherlands

Re: raytrace try

Post by bluatigro »

how do i do reflection ?

i got a solution but it isn't good

try :

Code: Select all

sub rotate( byref l as double , byref l as double , r as double )
  dim as double hk , hl , s = sin( r ) , c = cos( r )
  hk = k * c - l * s
  hl = k * s + l * c
  k = hk
  l = hl
end sub
function mirror( raydir as dbl3d , normal as dbl3d ) as dbl3d
  dim as double xz = atn( normal.x / normal.z )
  dim as double yz = atn( normal.y / normal.z )
  rotate normal.x , normal.z , -xz
  rotate raydir.x , raydir.z , -xz
  rotate normal.y , normal.z , -yz
  rotate raydir.y , raydir.z , -yz
  raddir.z *= -1
  rotate raydir.y , raydir.z , yz
  rotate raydir.x , raydir.z , xz
  return raydir
end function  
end function
bluatigro
Posts: 660
Joined: Apr 25, 2012 10:35
Location: netherlands

Re: raytrace try

Post by bluatigro »

made some smal mistakes !!!


i can't copy- paste the good code
bluatigro
Posts: 660
Joined: Apr 25, 2012 10:35
Location: netherlands

Re: raytrace try

Post by bluatigro »

update :
fount a new mirror() on www

error :
my screen gets purple

what is my typo ?

Code: Select all

''bluatigro 11 sept 2018
''triangle | sphere - ray

#include "t_3d.bas"
#include "basis_3d_m.bas"
#include "noise.bas"


DIM shared AS INTEGeR winx, winy, bitdepth
screen 20 , 32
SCREENINFO winx , winy , bitdepth

dim shared as t3d pnt( 256 )
sub setpoint( no as integer , a as double _
  , b as double , c as double )
  if no < 0 or no > ubound( pnt ) then exit sub
  spot a , b , c
  pnt( no ).x = a
  pnt( no ).y = b
  pnt( no ).z = c
end sub
type tmaterial
  dim as t3d ambient , diffuse , specular , emision
  dim as double shininess , reflection
end type
dim shared as tmaterial material
type triangle
public :
  dim as t3d punt( 2 ) , n , led 
  dim as tmaterial mat
  declare sub fill( p1 as integer , p2 as integer _
  , p3 as integer )
  declare function hit( o as t3d , d as t3d ) as double
end type
sub triangle.fill( p1 as integer , p2 as integer _
  , p3 as integer )
  if p1 < 0 or p1 > ubound( pnt ) then exit sub
  if p2 < 0 or p2 > ubound( pnt ) then exit sub
  if p3 < 0 or p3 > ubound( pnt ) then exit sub
  punt( 0 ) = pnt( p1 )
  punt( 1 ) = pnt( p2 )
  punt( 2 ) = pnt( p3 )
  led = ( punt( 0 ) + punt( 1 ) + punt( 2 ) ) / 3
  n = ( punt( 2 ) - punt( 0 ) ) \ ( punt( 1 ) - punt( 0 ) )
  n *= -1
  n = normalize( n )
  mat = material
end sub
function triangle.hit( o as t3d , d as t3d ) as double
  dim as t3d e1 = punt( 1 ) - punt( 0 )
  dim as t3d e2 = punt( 2 ) - punt( 0 )
  dim as t3d p = d \ e2
  dim as double a = dot( e1 , p )
  if abs( a ) < 1e-9 then return -1
  dim as double f = 1 / a
  dim as t3d s = o - punt( 0 )
  dim as double u = f * dot( s , p )
  if u < 0 or u > 1 then return -1
  dim as t3d q = s \ e1
  dim as double v = f * dot( d , q )
  if v < 0 or u + v > 1 then return -1
  return f * dot( e2 , q )
end function

dim shared as triangle triangles( 1000 )
dim shared as integer tritel = 0
sub tri( p1 as integer , p2 as integer _
  , p3 as integer )
  triangles( tritel ).fill p1 , p2 , p3
  tritel += 1
end sub
sub quad( p1 as integer , p2 as integer _
  , p3 as integer , p4 as integer )
  tri p1 , p2 , p3 
  tri p1 , p3 , p4
end sub
type Tbox
  m as t3d
  d as t3d
end type
dim shared box as Tbox
sub setbox( mx as double , my as double _
  , mz as double , dx as double _
  , dy as double , dz as double )
  box.m.x = mx
  box.m.y = my
  box.m.z = mz
  box.d.x = dx
  box.d.y = dy
  box.d.z = dz
end sub
sub torus( a as integer , b as integer )
  dim i as double , j as double , i2 as double , j2 as double
  if a < 3 then a = 3 
  if a > 64 then a = 64
  if b < 3 then b = 3 
  if b > 64 then b = 64 
  dim mx as double , my as double , mz as double , dx as double , dy as double , dz as double 
  mx = box.m.x 
  my = box.m.y 
  mz = box.m.z 
  dx = box.d.x 
  dy = box.d.y 
  dz = box.d.z 
  for i = -PI to PI  step PI / a * 2 
    i2 = i + PI / a * 2 
    for j = -PI to PI step PI / b * 2 
      j2 = j + PI / b * 2 
      setpoint 0 _ 
      , mx + ( dx + dy * cos( i ) ) * cos( j ) _
      , my + ( dx + dy * cos( i ) ) * sin( j ) _
      , mz + sin( i ) * dz  
      setpoint 1 _
      , mx + ( dx + dy * cos( i ) ) * cos( j2 ) _
      , my + ( dx + dy * cos( i ) ) * sin( j2 ) _
      , mz + sin( i ) * dz 
      setpoint 2 _
      , mx + ( dx + dy * cos( i2 ) ) * cos( j2 ) _
      , my + ( dx + dy * cos( i2 ) ) * sin( j2 ) _
      , mz + sin( i2 ) * dz 
      setpoint 3 _ 
      , mx + ( dx + dy * cos( i2 ) ) * cos( j ) _
      , my + ( dx + dy * cos( i2 ) ) * sin( j ) _
      , mz + sin( i2 ) * dz 
      quad 0 , 1 , 2 , 3 
    next j
  next i
end sub
sub cube()
  setpoint 0 , box.m.x + box.d.x , box.m.y + box.d.y , box.m.z + box.d.z
  setpoint 1 , box.m.x + box.d.x , box.m.y + box.d.y , box.m.z - box.d.z
  setpoint 2 , box.m.x + box.d.x , box.m.y - box.d.y , box.m.z + box.d.z
  setpoint 3 , box.m.x + box.d.x , box.m.y - box.d.y , box.m.z - box.d.z
  setpoint 4 , box.m.x - box.d.x , box.m.y + box.d.y , box.m.z + box.d.z
  setpoint 5 , box.m.x - box.d.x , box.m.y + box.d.y , box.m.z - box.d.z
  setpoint 6 , box.m.x - box.d.x , box.m.y - box.d.y , box.m.z + box.d.z
  setpoint 7 , box.m.x - box.d.x , box.m.y - box.d.y , box.m.z - box.d.z
  quad 0 , 2 , 3 , 1 ''right
  quad 7 , 6 , 4 , 5 ''left
  quad 0 , 4 , 5 , 1 ''up
  quad 7 , 3 , 2 , 6 ''down
  quad 0 , 4 , 6 , 2 ''back
  quad 7 , 5 , 1 , 3 ''front
end sub
sub cilinder( sides as integer , dx as single , dy as single )
  dim f as single
  if sides < 3 then sides = 3
  if sides > 64 then sides = 64
  for f = 0 to sides + 2
    setpoint f , box.m.x + sin( f * pi * 2 / sides ) * box.d.x _
               , box.m.y - box.d.y _
               , box.m.z + cos( f * pi * 2 / sides ) * box.d.z
    setpoint f + sides + 1 , box.m.x + sin( f * pi * 2 / sides ) * dx _
                           , box.m.y + box.d.y _
                           , box.m.z + cos( f * pi * 2 / sides ) * dy
  next f
  for f = 0 to sides + 1
    quad f , f + 1 , f + 2 + sides , f + 1 + sides 
  next f
    setpoint 255 , 0 , box.m.y + box.d.y , 0
    for f = 0 to sides
        setpoint f , box.m.x + sin( f * pi * 2 / sides ) * dx _
               , box.m.y + box.d.y _
               , box.m.z + cos( f * pi * 2 / sides ) * dy  
    next f
    for f = 0 to sides
      tri 255 , f , f + 1 
    next f
    setpoint 255 , 0 , box.m.y - box.d.y , 0
    for f = 0 to sides + 2
        setpoint f , box.m.x - sin( f * pi * 2 / sides ) * box.d.x _
               , box.m.y - box.d.y _
               , box.m.z + cos( f * pi * 2 / sides ) * box.d.z  
    next f
    for f = 0 to sides + 2
      tri 255 , f , f + 1 
    next f
end sub

type tSphere
  dim as t3d center
  dim as tmaterial mat
  dim as double radius , radius2
  declare sub fill( c as t3d , r as double )
  declare function hit( o as t3d , d as t3d ) as double 
  declare function normal( nu as t3d ) as t3d
end type
sub tSphere.fill( c as t3d , r as double )
  spot c.x , c.y , c.z
  center = c
  radius = r
  radius2 = r * r
  mat = material
end sub
const as double infinity = 1e9
function tSphere.hit( o as t3d , d as t3d ) as double
  dim as double t , a , b , c , disc
  dim as t3d temp = o - center
  a = dot( d , d )
  b = 2 * dot( temp , d )
  c = dot( temp , temp ) - radius2
  disc = b ^ 2 - 4 * a * c
  if disc < 0 then 
    return infinity
  else
    dim as double e = sqr( disc ) 
    dim as double demon = 2 * a
    t = ( -b - e ) / demon
    if t > 1e-12 then
      return t
    end if
    
    t = ( -b + e ) / demon
    if t > 1e-12 then 
      return t
    end if
  end if
  return infinity
end function
function tSphere.normal( nu as t3d ) as t3d
  return nu - center
end function
dim shared as tSphere spheres( 1000 )
dim shared as integer spheretel
sub sphere2( c as t3d , r as double )
  spheres( spheretel ).fill c , r 
  spheretel += 1
end sub
sub sphere( a as double , b as double , c as double _
  , r as double , kl as t3d )
  material.diffuse = kl
  spheres( spheretel ).fill t3d( a , b , c ) , r
  spheretel += 1
end sub
function mirror2( d as t3d , q as t3d ) as t3d
  dim as double ha , hb
  ha = atan2( q.y , q.z ) * 180 / pi
  rotate q.y , q.z , -ha 
  rotate d.y , d.z , -ha 
  hb = atan2( q.x , q.z ) * 180 / pi
  rotate q.x , q.z , -hb 
  rotate d.x , d.z , -hb
  d.z *= -1
  rotate d.x , d.z , hb 
  rotate d.y , d.z , ha 
  return d
end function
function mirror( d as t3d , n as t3d ) as t3d
  dim as double cos1 = -dot( n , d )
  return d + n * 2 * cos1
end function
dim shared as t3d light
light.fill -1 , 3 , 1
type t_fog
  dim as t3d kl
  dim as double dist , height
  dim as integer visable
end type
dim shared as t_fog fog
function renderPixel( o as t3d , d as t3d _
  , dept as integer ) as t3d
  dim as integer i , id = -1 , id2 = -1 
  dim as double dist , tridist = infinity , sphdist = infinity , a 
  dim as t3d kl , kl2 , ambient , diffuse _
  , specular , emision , q , p , shade , uit
  dim as double shininess , reflection
  for i = 0 to tritel
    dist = triangles( i ).hit( o , d )
    if dist < tridist then
      id = i
      tridist = dist
    end if
  next i
  for i = 0 to spheretel
    dist = spheres( i ).hit( o , d )
    if dist < sphdist then
      id2 = i
      sphdist = dist
    end if
  next i
  if id = -1 and id2 = -1 then
    if fog.visable then
      return fog.kl
    else
      return t3d()
    end if
  end if
  if tridist < sphdist then 
    reflection = triangles( id ).mat.reflection
    ''color objects from triangle
    ''how do i calc the end color ?
    ambient = triangles( id ).mat.ambient
    diffuse = triangles( id ).mat.diffuse
    specular = triangles( id ).mat.specular
    emision = triangles( id ).mat.emision
    shininess = triangles( id ).mat.shininess
    a = angle( triangles( id ).n , light )
    kl = diffuse * ( cos( a ) / 2 + 0.5 )
    p = o + d * tridist
''    if renderPixel( p , light , -1 ) <> t3d() then 
''      kl = t3d()
''    end if
    if fog.visable then
      kl = t3dmix( kl , tridist / 10 , fog.kl )
    end if
    if reflection < 0.001 or dept < 0 then
      return kl
    else
      q = triangles( id ).n
      d = mirror( d , q )
      kl2 = renderPixel( p , d , dept - 1 )
      return kl + ( kl2 - kl ) * reflection
    end if
  else
    reflection = spheres( id2 ).mat.reflection
    ''color objects from sphere
    ''how do i calc the end color ?
    ambient = spheres( id2 ).mat.ambient
    diffuse = spheres( id2 ).mat.diffuse
    specular = spheres( id2 ).mat.specular
    emision = spheres( id2 ).mat.emision
    shininess = spheres( id2 ).mat.shininess
    p = o + d * sphdist
    q = spheres( id2 ).normal( p )
    q = normalize(q)
    a = angle( q , light )
    kl = diffuse * ( cos( a ) / 2 + 0.5 )
''    if a < pi/2 then
''      kl2 = renderpixel( p , light , -1 )
''      if kl2.x or kl2.y or kl2.z then
''        return t3d()
''      end if
''    end if
    if fog.visable then
      kl = t3dmix( kl , sphdist / 10 , fog.kl )
    end if
    if reflection < 0.001 or dept < 0 then
      return kl
    else
      d = mirror( d , q )
      kl2 = renderPixel( p , d , dept - 1 )
      return kl + ( kl2 - kl ) * reflection
    end if
  end if
  if fog.visable then return fog.kl
  return t3d()
end function
dim shared as t3d black , red , green , yellow , blue _
, magenta , cyan , white , gray , pink , orange
black.fill   0  , 0  , 0
red.fill     1  , 0  , 0
green.fill   0  , 1  , 0
yellow.fill  1  , 1  , 0
blue.fill    0  , 0  , 1
magenta.fill 1  , 0  , 1
cyan.fill    0  , 1  , 1
white.fill   1  , 1  , 1
gray.fill    .5 , .5 , .5
pink.fill    1  , .5 , .5
orange.fill  1  , .5 , 0

const as integer arm   = 1
const as integer elbow = 2
const as integer wrist = 3
const as integer leg   = 4
const as integer knee  = 5
const as integer enkle = 6
const as integer neck  = 7
const as integer eye   = 8
const as integer wenk  = 9
const as integer tail  = 10
const as integer thumb = 11
const as integer index = 14
const as integer midle = 17
const as integer ring  = 20
const as integer lr    = 32

Sub Kop( qq as integer , kl as t3d )
    link 15, 0, 0, 0, 0, 0, 0,xyz, number
        sphere 0, 0, 0, 30, kl
    If qq = 1 Then
        sphere 25, 25, 0, 9, kl
        sphere -25, 25, 0, 9, kl
        sphere 0, 0, -40, 12, gray
    Else
        sphere 30, 0, 0, 9, kl
        sphere -30, 0, 0, 9, kl
        sphere 0, 0, -40, 12, kl
    End If
        child 16, 14, 14, -14, eye ,xyz, 15
          sphere 0, 0, 0, 13, white
          sphere 0, 0, -10, 7, black
        child 16, -14, 14, -14, eye + lr,xyz, 15
          sphere 0, 0, 0, 13, white
          sphere 0, 0, -10, 7, black
End Sub


sub man( trui as t3d , broek as t3d )
    link 9 , 0,0,0 , 0,0,0 , xyz , number
        sphere 0, 50, 0, 30, trui
        sphere 0, 25, 0, 23, broek
        sphere 0, 0, 0, 15, broek
    child 11, 0, 70, 0, neck, xyz, 9
    child 12, 0, 30, 0, neck+lr, xyz, 11
        Kop 0, pink
    child 11, 20, -10, 0, leg, yzx, 9
        sphere 0, 0, 0, 16, broek
        sphere 0, -20, 0, 16, broek
    child 12, 0, -40, 0, knee, xyz, 11
        sphere 0, 0, 0, 16, broek
        sphere 0, -20, 0, 16, broek
    child 13, 0, -40, 0, enkle, xzy, 12
        sphere 0, 0, 0, 12, gray
        sphere 0, 0, -20, 12, gray
    child 11, -20, -10, 0, leg+lr , yzx, 9
        sphere 0, 0, 0, 16, broek
        sphere 0, -20, 0, 16, broek
    child 12, 0, -40, 0, knee+lr, xyz, 11
        sphere 0, 0, 0, 16, broek
        sphere 0, -20, 0,16, broek
    child 13, 0, -40, 0,enkle+lr, xzy, 12
        sphere 0, 0, 0, 12, gray
        sphere 0, 0, -20, 12, gray
    child 11, 40, 60, 0, arm, xzy, 9
        sphere 0, 0, 0, 16, trui
        sphere 6, -20, 0, 12, trui
    child 12, 6, -40, 0, elbow, xyz, 11
        sphere 0, 0, 0, 12, trui
        sphere 0, -20, 0, 12, trui
        sphere 0, -42, 0, 8, pink
    child 11, -40, 60, 0, arm+lr, xzy, 9
        sphere 0, 0, 0, 16, trui
        sphere -6, -20, 0, 12, trui
    child 12, -6, -40, 0, elbow+lr, xyz, 11
        sphere 0, 0, 0, 12, trui
        sphere 0, -20, 0, 12, trui
        sphere 0, -42, 0, 8, pink
end sub
sub man_walk( f as double , a as double )
    skelet arm , pend( f , a ) , 0 , 0
    skelet elbow , -abs( a ) , 0 , 0
    skelet arm + lr , pend( f + 180, a ) , 0 , 0
    skelet elbow + lr , -abs( a ) , 0 , 0
    skelet leg , pend( f + 180 , a ) , 0 , 0
    skelet knee , pend( f + 90 , a ) + a , 0 , 0
    skelet leg + lr , pend( f , a ) , 0 , 0
    skelet knee + lr , pend( f - 90 , a ) + a , 0 , 0
end sub
sub dog_walk( f as double , a as double )
    skelet arm , pend( f , a ) , 0 , 0
    skelet elbow , pend( f - 90 , a ) + a , 0 , 0
    skelet arm + lr , pend( f + 180, a ) , 0 , 0
    skelet elbow + lr , pend( f + 90 , a ) + a , 0 , 0
    skelet leg , pend( f + 180 , a ) , 0 , 0
    skelet knee , pend( f + 90 , a ) + a , 0 , 0
    skelet leg + lr , pend( f , a ) , 0 , 0
    skelet knee + lr , pend( f - 90 , a ) + a , 0 , 0
    skelet tail , -a , pend( f * 2 , a ) , 0
end sub

sub pilko( kl as t3d )
  sphere 0,0,0,30 , kl
  sphere 0,0,50,30 , kl
  child 2 , 0,20,-20 , neck , xyz , 1
    child 3 , 0,20,-20 , neck , zyx , 2
      kop 1 , kl
  child 11, -20, -10, 50, leg, yzx, 1
    sphere 0, 0, 0, 16, kl
    sphere 0, -20, 0, 16, kl
    child 12, 0, -40, 0, knee, xyz, 11
      sphere 0, 0, 0, 16, kl
      sphere 0, -20, 0, 16, kl
      child 13, 0, -40, 0, enkle, xzy, 12
        sphere 0, 0, 0, 12, kl
        sphere 0, 0, -20, 12, kl
  child 11, 20, -10, 50, leg+lr, yzx, 1
    sphere 0, 0, 0, 16, kl
    sphere 0, -20, 0, 16, kl
    child 12, 0, -40, 0, knee+lr, xyz, 11
      sphere 0, 0, 0, 16, kl
      sphere 0, -20, 0, 16, kl
      child 13, 0, -40, 0, enkle+lr, xzy, 12
        sphere 0, 0, 0, 12, kl
        sphere 0, 0, -20, 12, kl
  child 11, 20, -10, 0, arm, yzx, 1
    sphere 0, 0, 0, 16, kl
    sphere 0, -20, 0, 16, kl
    child 12, 0, -40, 0, elbow, xyz, 11
      sphere 0, 0, 0, 16, kl
      sphere 0, -20, 0, 16, kl
      child 13, 0, -40, 0, wrist, xzy, 12
        sphere 0, 0, 0, 12, kl
        sphere 0, 0, -20, 12, kl
  child 11, -20, -10, 0, arm+lr, yzx, 1
    sphere 0, 0, 0, 16, kl
    sphere 0, -20, 0, 16, kl
    child 12, 0, -40, 0, elbow+lr, xyz, 11
      sphere 0, 0, 0, 16, kl
      sphere 0, -20, 0, 16, kl
      child 13, 0, -40, 0, wrist+lr, xzy, 12
        sphere 0, 0, 0, 12, kl
        sphere 0, 0, -20, 12, kl
  child 3 , 0,14,90 , tail , xyz , 2
    dim i as integer
    for i = 0 to 5
      sphere 0,i*8,0,10 , kl
    next i
end sub
sub saveframe( f as string , no as integer , m as integer )
  bsave f + nr( no , m ) + ".bmp" , 0
end sub
dim as double frame
''for frame = 0 to 35
tritel = 0
spheretel = 0
material.reflection = 0.5
link 1 , -150,100,0 , frame*10,0,0 , xyz , 0
material.diffuse = magenta
sphere2 t3d( -150 , 150*0.86 , 0 ) , 70 
material.diffuse = cyan
sphere2 t3d( 150 , 150*0.86 , 0 ) , 70 
material.diffuse = yellow
sphere2 t3d( 0 , -150 , 0 ) , 70 
material.diffuse = red
sphere2 t3d( -150 , -150*0.86 , 0 ) , 70 
material.diffuse = green
sphere2 t3d( 150 , -150*0.86 , 0 ) , 70 
material.diffuse = blue
sphere2 t3d( 0 , 150 , 0 ) , 70 

''link 1 , 0,0,0 , 0,0,0 , xyz , 0
''material.reflection = 0
''material.diffuse = gray
''setbox 0,0,0 , 300,50,50
''torus 12 , 12 

''matèrial.reflection = 0.5
link 2 , 0,0,0 , 0,0,0 , xyz , 0
material.diffuse.fill .2 , .5 , .2
''sphere2 t3d( 0 , -1e5-100 , 0 ) , 1e5

material.reflection = 0
link 1 , 150,0,500 ,180,0,0 , xyz , 0
man_walk frame * 10 , 30
man yellow , blue
link 1 , -150,0,500 , 140,0,0 , xyz , 0
dog_walk frame * 10 , 30
pilko orange

dim as double i
link 1 , 150,100,0 , 0,0,0 , xyz , 0
material.diffuse = white
for i = 0 to 10
  material.reflection = i / 10
  sphere2 t3d( -50 * i , 0 , 0 ) , 25
next i
  
link 1 , 200,100,0 , 45,-30,0 , xyz , 0
material.reflection = 0
material.diffuse = magenta
setbox 0,0,0 , 50,50,50
cube
material.diffuse = cyan
setbox 0,200,0 , 50,50,50
cilinder 12 , 20 , 20

''fog.visable = 1
''fog.kl = gray
''fog.dist = 10

dim as double x , y
dim as t3d o , d
paint( 1 , 1 ) , rgb( 255 , 255 , 255 )
for x = -winx / 2 to winx / 2
  for y = -winy / 2 to winy / 2
    o.fill 0 , 0 , 1000
    d.fill x , y , -1000
    pset( x + winx / 2 , winy / 2 - y ) _
    , renderPixel( o , d , 7 ).toColor
  next y
next x
''saveframe "bmp\man" , cint( frame ) , 3
bsave "tri-sphere.bmp" , 0
''next frame
print "ready"
sleep
screen 0
bluatigro
Posts: 660
Joined: Apr 25, 2012 10:35
Location: netherlands

Re: raytrace try

Post by bluatigro »

update :
i fount some math formula's
i can not translate them in basic
it is +-30year ago i studied math
i do not understand it al
i need some help

see for math :
https://www.cl.cam.ac.uk/teaching/1999/ ... 0000000000

the folowing works but is extreemly slow

Code: Select all

'' bluatigro 3 okt 2018
'' slow ray 1
'' this can be speeded up if i undestand :
''https://www.cl.cam.ac.uk/teaching/1999/AGraphHCI/SMAG/node2.html#SECTION00023100000000000000
type d3d
  dim as double x , y , z 
  declare constructor ()
  declare constructor ( a as double , b as double , c as double )
  declare function tocolor() as ulong
end type
constructor d3d()
  x = 0
  y = 0
  z = 0
end constructor
constructor d3d( a as double , b as double , c as double )
  x = a
  y = b
  z = c
end constructor
operator + ( a as d3d , b as d3d ) as d3d
  return d3d( a.x + b.x , a.y + b.y , a.z + b.z )
end operator
operator - ( a as d3d , b as d3d ) as d3d
  return d3d( a.x - b.x , a.y - b.y , a.z - b.z )
end operator
function d3d.tocolor() as ulong
  return rgb( x * 255 , y * 255 , z * 255 )
end function

type tsphere
  dim as d3d c , kl
  dim as double d
  declare function hit( nu as d3d ) as integer
end type
function tsphere.hit( nu as d3d ) as integer
  nu = nu - c
  return sqr( nu.x ^ 2 + nu.y ^ 2 + nu.z ^ 2 ) < d
end function
type tcylinder
  dim as d3d c , kl
  dim as double d , h
  declare function hit( nu as d3d ) as integer
end type
function tcylinder.hit( nu as d3d ) as integer
  nu = nu - c
  return sqr( nu.x ^ 2 + nu.z  ^ 2 ) < d and abs( nu.y ) < h
end function
type tcone
  dim as d3d c , kl
  dim as double d , h
  declare function hit( nu as d3d ) as integer
end type
function tcone.hit( nu as d3d ) as integer
  nu = nu - c
  return sqr( nu.x ^ 2 + nu.z ^ 2 ) < nu.z / h / 2 * d and abs( nu.y ) < h 
end function

dim as tsphere sphere
sphere.c = d3d( -300 , 0 , 1000 )
sphere.d = 50
sphere.kl= d3d( 1 , 0 , 0 ) ''red
dim as tcylinder cylinder
cylinder.c = d3d( 0 , 0 , 1000 )
cylinder.d = 30
cylinder.h = 70
cylinder.kl = d3d( 0 , 1 , 0 ) ''green
dim as tcone cone
cone.c = d3d( 300 , 0 , 1000 ) 
cone.d = 50
cone.h = 100
cone.kl = d3d( 0 , 0 , 1 ) ''blue

screen 20 , 32 
dim as integer winx , winy
screeninfo winx , winy
dim as d3d nu , dnu
dim as double x , y
dim as ulong kl
paint ( 1 , 1 ) , &h7f7f7f
for x = -winx / 2 to winx / 2
  for y = -winy / 2 to winy / 2
    nu = d3d( x , y , 0 )
    dnu = d3d( x / winx , y / winy , 1 )
    while not sphere.hit( nu ) _
    and not cylinder.hit( nu ) _
    and not cone.hit( nu ) _
    and nu.z < 3000
      nu += dnu
      dnu += d3d( .01 , .01 , .01 )
    wend
    kl = rgb(0,0,0)
    if sphere.hit( nu ) then kl = sphere.kl.tocolor()
    if cylinder.hit( nu ) then kl = cylinder.kl.tocolor()
    if cone.hit( nu ) then kl = cone.kl.tocolor()
    pset ( x + winx / 2 , y + winy / 2 ) , kl
  next y
next x
print "ready"
sleep 
who help's create a raytracing shapes set to play whit ?
dafhi
Posts: 1640
Joined: Jun 04, 2005 9:51

Re: raytrace try

Post by dafhi »

it looks like you're performing a variation of ray marching

avoid sqr() and ^

Code: Select all

function tsphere.hit( nu as d3d ) as integer
  nu = nu - c
  return ( nu.x*nu.x + nu.y*nu.y + nu.z*nu.z) < d*d
  'return sqr( nu.x ^ 2 + nu.y ^ 2 + nu.z ^ 2 ) < d
end function

Code: Select all

      dnu += d3d( .5 , .5 , .5 )
Stonemonkey
Posts: 649
Joined: Jun 09, 2005 0:08

Re: raytrace try

Post by Stonemonkey »

Hi, to reflect you have to reverse the vectors direction with respect to the normal of the point it intersects the surface.
It's something like this I think

Code: Select all

s=-2.0*dot(vector,normal)
vector+=s*normal
You can also reflect the light vector and compare (dot) that with the eye or camera vector to calculate specular lighting. The result has to be clamped and the bright spots will be quite big so I do something like multiply the result by itself a few times to give sharper spots and make things more shiny.
dafhi
Posts: 1640
Joined: Jun 04, 2005 9:51

Re: raytrace try

Post by dafhi »

Stonemonkey, good to see you!

rough reflections (from my path tracer)

Code: Select all

function tracer.norm_scatter(rayd as v3, abscosi as single, k as single) as v3

  ' Maths description:
  
  ' randomize the reflection normal in a cone
  ' at minimum roughness (k=0), cone center is parallel with surface normal. the cone spread is also zero.
  ' at maximum roughness (k=1), cone center points halfway between ray and surf norm, cone spread is 90 degrees.
 
  dim as v3 perp = rayd - stack(depth).norm * abscosi
  dim as single angle = atan2(sqr(1-abscosi*abscosi), abscosi)*.5*k
  dim as single cosa = cos(angle), sina = sin(angle)
  dim as v3 newnorm = stack(depth).norm*cosa + perp.n*sina
  angle = (1-sqr(rnd))*k*piBy4 '' 2017 Dec 25
  cosa=cos(angle):  sina=sin(angle)
  k = rnd*twopi
  perp = newnorm.perp(cos(k)*sina)
  return newnorm*cosa + perp + newnorm.cross(perp, sin(k)*sina)
 
end function
abscosi example

Code: Select all

  /' 
      .cosi = ray->d.dot(.norm)
      .rayd = -ray->d
      if [reflection amount]<>0 then
        .nrand = norm_scatter(.rayd, -.cosi, .mat->o.refl.k)
        .ray_refl = type(.hp, ray->d - .nrand*ray->d.dot(.nrand)*2)
        trace_ @.ray_refl
  '/
bluatigro
Posts: 660
Joined: Apr 25, 2012 10:35
Location: netherlands

Re: raytrace try

Post by bluatigro »

update :
build it in
not fast enoug jet

error :
only black pixel's

i m using a point traveling trough the world
i know that it can be done whit a ray
then it wood take sec in place of min to draw a BMP

buiding this whit a ray : who helps ?

Code: Select all

'' bluatigro 3 okt 2018
'' slow ray 1
'' this can be speeded up if i undestand :
''https://www.cl.cam.ac.uk/teaching/1999/AGraphHCI/SMAG/node2.html#SECTION00023100000000000000
type d3d
  dim as double x , y , z 
  declare constructor ()
  declare constructor ( a as double , b as double , c as double )
  declare function tocolor() as ulong
end type
constructor d3d()
  x = 0
  y = 0
  z = 0
end constructor
constructor d3d( a as double , b as double , c as double )
  x = a
  y = b
  z = c
end constructor
operator + ( a as d3d , b as d3d ) as d3d
  return d3d( a.x + b.x , a.y + b.y , a.z + b.z )
end operator
operator - ( a as d3d , b as d3d ) as d3d
  return d3d( a.x - b.x , a.y - b.y , a.z - b.z )
end operator
function d3d.tocolor() as ulong
  return rgb( x * 255 , y * 255 , z * 255 )
end function

type tsphere
  dim as d3d c , kl
  dim as double d
  declare function hit( nu as d3d ) as integer
end type
function tsphere.hit( nu as d3d ) as integer
  nu = nu - c
  return ( nu.x * nu.x + nu.y * nu.y + nu.z * nu.z ) < d * d
end function
type tcylinder
  dim as d3d c , kl
  dim as double d , h
  declare function hit( nu as d3d ) as integer
end type
function tcylinder.hit( nu as d3d ) as integer
  nu = nu - c
  return ( nu.x * nu.x + nu.z  * nu.z ) < d * d and abs( nu.y ) < h
end function
type tcone
  dim as d3d c , kl
  dim as double d , h
  declare function hit( nu as d3d ) as integer
end type
function tcone.hit( nu as d3d ) as integer
  nu = nu - c
  return ( nu.x * nu.x + nu.z * nu.z ) < ( nu.z * nu.z ) / ( h * h ) * ( d * d ) and abs( nu.y ) < h 
end function

dim as tsphere sphere
sphere.c = d3d( -150 , 0 , 1000 )
sphere.d = 50
sphere.kl= d3d( 1 , 0 , 0 ) ''red
dim as tcylinder cylinder
cylinder.c = d3d( 0 , 0 , 1000 )
cylinder.d = 30
cylinder.h = 70
cylinder.kl = d3d( 0 , 1 , 0 ) ''green
dim as tcone cone
cone.c = d3d( 150 , 0 , 1000 ) 
cone.d = 50
cone.h = 100
cone.kl = d3d( 0 , 0 , 1 ) ''blue

screen 20 , 32 
dim as integer winx , winy
screeninfo winx , winy
dim as d3d nu , dnu
dim as double x , y
dim as ulong kl
paint ( 1 , 1 ) , &h7f7f7f
for x = -250 to 250
  for y = -120 to 120
    nu = d3d( x , y , 930 )
    dnu = d3d( 0 , 0 , 2 )
    while not sphere.hit( nu ) _
    and not cylinder.hit( nu ) _
    and not cone.hit( nu ) _
    and nu.z < 1070
      nu += dnu
      dnu += d3d( 0 , 0 , 1 )
    wend
    kl = rgb(0,0,0)
    if sphere.hit( nu ) then kl = sphere.kl.tocolor()
    if cylinder.hit( nu ) then kl = cylinder.kl.tocolor()
    if cone.hit( nu ) then kl = cone.kl.tocolor()
    pset ( x + winx / 2 , y + winy / 2 ) , kl
  next y
next x
print "ready"
sleep 
Post Reply