raytrace try

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

raytrace try

Postby bluatigro » Sep 21, 2017 8:13

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: 448
Joined: Apr 25, 2012 10:35
Location: netherlands

Re: raytrace try

Postby bluatigro » Sep 21, 2017 8:55

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: 448
Joined: Apr 25, 2012 10:35
Location: netherlands

Re: raytrace try

Postby bluatigro » Sep 25, 2017 8:45

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


Return to “General”

Who is online

Users browsing this forum: No registered users and 3 guests