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