Code: Select all
'' bluatigro 7 dec 2018
'' bluaray 2 material
#include "noise.bas"
dim shared as integer winx , winy
screen 20 , 32
screeninfo winx , winy
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
function d3d.tocolor() as ulong
return rgb( x * 255 , y * 255 , z * 255 )
end function
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
operator * ( a as d3d , b as double ) as d3d
return d3d( a.x * b , a.y * b , a.z * b )
end operator
operator / ( a as d3d , b as double ) as d3d
return d3d( a.x / b , a.y / b , a.z / b )
end operator
operator \ ( a as d3d , b as d3d ) as d3d
return d3d( a.y * b.x - a.z * b.y _
, a.z * b.x - a.x * b.z _
, a.x * b.z - a.y * b.x )
end operator
function dot( a as d3d , b as d3d ) as double
return a.x * b.x + a.y * b.y + a.z * b.z
end function
function lenght( a as d3d ) as double
return sqr( dot( a , a ) )
end function
function getangle( a as d3d , b as d3d ) as double
return acos( dot( a , b ) _
/ ( lenght( a ) * lenght( b ) ) )
end function
type m33
dim as double e( 3 , 3 )
declare constructor()
declare constructor( _
a11 as double , a12 as double , a13 as double _
, a21 as double , a22 as double , a23 as double _
, a31 as double , a32 as double , a33 as double )
declare function inverse() as m33
end type
constructor m33()
e(0,0) = 1
e(0,1) = 0
e(0,2) = 0
e(0,3) = 0
e(1,0) = 0
e(1,1) = 1
e(1,2) = 0
e(1,3) = 0
e(2,0) = 0
e(2,1) = 0
e(2,2) = 1
e(2,3) = 0
e(3,0) = 0
e(3,1) = 0
e(3,2) = 0
e(3,3) = 1
end constructor
constructor m33( _
a11 as double , a12 as double , a13 as double _
, a21 as double , a22 as double , a23 as double _
, a31 as double , a32 as double , a33 as double )
e(0,0) = a11
e(0,1) = a12
e(0,2) = a13
e(0,3) = 0
e(1,0) = a21
e(1,1) = a22
e(1,2) = a23
e(1,3) = 0
e(2,0) = a31
e(2,1) = a32
e(2,2) = a33
e(2,3) = 0
e(3,0) = 0
e(3,1) = 0
e(3,2) = 0
e(3,3) = 1
end constructor
operator * ( a as m33 , b as m33 ) as m33
dim as m33 uit
dim as integer i , j , k
for i = 0 to 3
for j = 0 to 3
uit.e( i , j ) = 0
for k = 0 to 3
uit.e( i , j ) += a.e( i , k ) * b.e( k , j )
next k
next j
next i
return uit
end operator
function m33.inverse() as m33
dim as double d = e(0,0) * e(1,1) * e(2,2) _
- e(0,0) * e(2,1) * e(1,2) _
+ e(1,0) * e(2,1) * e(0,2) _
- e(1,0) * e(0,1) * e(2,2) _
+ e(2,0) * e(0,1) * e(1,2) _
- e(2,0) * e(1,1) * e(0,2)
if d = 0 then d = 1
d = 1 / d
return m33( ( e(1,1) * e(2,2) - e(1,2) * e(2,1) ) * d _
, -( e(0,1) * e(2,2) - e(0,2) * e(2,1) ) * d _
, ( e(0,1) * e(1,2) - e(0,2) * e(1,1) ) * d _
, -( e(1,0) * e(2,2) - e(1,2) * e(2,0) ) * d _
, ( e(0,0) * e(2,2) - e(0,2) * e(2,0) ) * d _
, -( e(0,0) * e(1,2) - e(0,2) * e(1,0) ) * d _
, ( e(1,0) * e(2,1) - e(1,1) * e(2,0) ) * d _
, -( e(0,0) * e(2,1) - e(0,1) * e(2,0) ) * d _
, ( e(0,0) * e(1,1) - e(0,1) * e(1,0) ) * d )
end function
operator * ( m as m33 , v as d3d ) as d3d
return d3d( _
m.e(0,0) * v.x + m.e(0,1) * v.y + m.e(0,2) * v.z _
, m.e(1,0) * v.x + m.e(1,1) * v.y + m.e(1,2) * v.z _
, m.e(2,0) * v.x + m.e(2,1) * v.y + m.e(2,2) * v.z )
end operator
dim shared as m33 mv( 20 )
dim shared as integer matrix_number
sub spot( byref x as double _
, byref y as double _
, byref z as double )
dim as d3d temp = d3d( x , y , z )
temp = mv( matrix_number ) * temp
x = temp.x
y = temp.y
z = temp.z
end sub
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
const as double pi = atn( 1 ) * 4
function rad( x as double ) as double
return x * pi / 180
end function
function pend( f as double , a as double ) as double
''pendular motion for animation
''looks verry natural
return sin( rad( f ) ) * a
end function
dim shared as double sk( 100 , 2 )
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
dim shared as double cam( 6 )
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 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
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 m33 mp , rotx , roty , rotz , translate
mp = mv( p )
rotz.e(0,0) = Cos( rad( rol ))
rotz.e(0,1) = -Sin( rad( rol ))
rotz.e(1,0) = Sin( rad( rol ))
rotz.e(1,1) = Cos( rad( rol ))
roty.e(0,0) = Cos( rad( pan ))
roty.e(0,2) = -Sin( rad( pan ))
roty.e(2,0) = Sin( rad( pan ))
roty.e(2,2) = Cos( rad( pan ))
rotx.e(1,1) = Cos( rad( tilt ))
rotx.e(1,2) = -Sin( rad( tilt ))
rotx.e(2,1) = Sin( rad( tilt ))
rotx.e(2,2) = Cos( rad( tilt ))
translate.e(3,0) = x
translate.e(3,1) = y
translate.e(3,2) = z
''angles can permutate 6 ways
Select Case ax
Case xyz
mv( no ) = rotx * roty * rotz * translate * mp
Case xzy
mv( no ) = rotx * rotz * roty * translate * mp
Case yxz
mv( no ) = roty * rotx * rotz * translate * mp
Case yzx
mv( no ) = roty * rotz * rotx * translate * mp
Case zxy
mv( no ) = rotz * rotx * roty * translate * mp
Case zyx
mv( no ) = rotz * roty * rotx * translate * mp
Case Else
End Select
matrix_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 lokal( byref x as double , byref y as double _
, byref z as double , q as m33 )
dim as d3d temp = d3d( x , y , z )
temp = q * temp
x = temp.x
y = temp.y
z = temp.z
end sub
const as integer turbulence = 1
const as integer wave = 2
dim shared as d3d black = d3d( 0 , 0 , 0 )
dim shared as d3d red = d3d( 1 , 0 , 0 )
dim shared as d3d green = d3d( 0 , 1 , 0 )
dim shared as d3d yellow = d3d( 1 , 1 , 0 )
dim shared as d3d blue = d3d( 0 , 0 , 1 )
dim shared as d3d magenta = d3d( 1 , 0 , 1 )
dim shared as d3d cyan = d3d( 0 , 1 , 1 )
dim shared as d3d white = d3d( 1 , 1 , 1 )
type tmaterial
dim as d3d diffuse( 10 ) , scale
dim as double grens( 11 ) , turbsize , wavesize
dim as integer kleurmax , mattype
declare constructor ()
declare sub filldiffuse( a as d3d , b as d3d , c as d3d , d as d3d _
, e as d3d , f as d3d , g as d3d , h as d3d )
declare sub fillgrens( a as double , b as double , c as double , d as double _
, e as double , f as double , g as double , h as double )
end type
constructor tmaterial()
dim as integer i
for i = 0 to 10
diffuse( i ) = d3d( 1 , 1 , 1 )
grens( i + 1 ) = 1
next i
kleurmax = 1
scale = d3d( 1 , 1 , 1 )
mattype = turbulence
turbsize = 0
wavesize = 0
end constructor
sub tmaterial.filldiffuse( a as d3d , b as d3d , c as d3d , d as d3d _
, e as d3d , f as d3d , g as d3d , h as d3d )
diffuse( 0 ) = a
diffuse( 1 ) = b
diffuse( 2 ) = c
diffuse( 3 ) = d
diffuse( 4 ) = e
diffuse( 5 ) = f
diffuse( 6 ) = g
diffuse( 7 ) = h
end sub
sub tmaterial.fillgrens( a as double , b as double , c as double , d as double _
, e as double , f as double , g as double , h as double )
grens( 0 ) = 0
grens( 1 ) = a
grens( 2 ) = b
grens( 3 ) = c
grens( 4 ) = d
grens( 5 ) = e
grens( 6 ) = f
grens( 7 ) = g
grens( 8 ) = h
end sub
dim shared as tmaterial material
dim shared as integer spheretel
const as integer spheremax = 100
type tSphere
dim as d3d center
dim as tmaterial mat
dim as m33 mp
dim as double radius , radius2
declare sub fill( c as d3d , r as double )
declare function hit( o as d3d , d as d3d ) as double
end type
sub tSphere.fill( c as d3d , r as double )
spot c.x , c.y , c.z
center = c
radius = r
radius2 = r * r
mat = material
mp = mv( matrix_number ).inverse()
end sub
const as double infinity = 1e9
function tSphere.hit( o as d3d , d as d3d ) as double
dim as double t , a , b , c , disc
dim as d3d 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
dim shared as tSphere spheres( spheremax )
sub addsphere( x as double , y as double , z as double , d as double , m as tmaterial )
material = m
spheres( spheretel ).fill d3d( x , y , z ) , d
spheretel += 1
end sub
function pixel( o as d3d , d as d3d ) as d3d
dim as integer i , klno , isph = -1
dim as double dist , slow = infinity
for i = 0 to spheretel
dist = spheres( i ).hit( o , d )
if dist < slow then
slow = dist
isph = i
end if
next i
if isph = -1 then return black
dim as tsphere bol = spheres( isph )
dim as d3d n , p , plek
p = o + d * slow
n = p - bol.center
plek = n
lokal plek.x , plek.y , plek.z , bol.mp
dim as double dd
if bol.mat.mattype and turbulence then
dd = turbulence3d( _
( plek.x + bol.radius ) / bol.mat.scale.x _
, ( plek.y + bol.radius ) / bol.mat.scale.y _
, ( plek.z + bol.radius ) / bol.mat.scale.z , 64 )
dd = dd * bol.mat.turbsize
end if
if bol.mat.mattype and wave then
dd = sin( plek.y * bol.mat.wavesize + dd ) / 2 + .5
end if
klno = 0
for i = 0 to bol.mat.kleurmax
if ( bol.mat.grens( i ) <= dd _
and bol.mat.grens( i + 1 ) > dd ) then
klno = i
end if
next i
dim as d3d kll = bol.mat.diffuse( klno )
dim as d3d klh = bol.mat.diffuse( klno + 1 )
dim as double gl = bol.mat.grens( klno )
dim as double gh = bol.mat.grens( klno + 1 )
dim as double f = ( dd - gl ) / ( gh - gl )
dim as d3d kl = kll + ( klh - kll ) * f
dim as double a = getangle( n , d3d(-1,1,0) )
return kl * ( cos( a ) / 2 + .5 )
end function
dim shared as tmaterial earth , moon , mars , jupiter , neptune
earth.filldiffuse blue , cyan , yellow , green , white / 2 , white , red , red
earth.fillgrens .5 , .6 , .7 , .8 , .9 , 1 , 1 , 1
earth.kleurmax = 6
earth.scale = d3d( 1/3 , 1/3 , 1/3 )
earth.mattype = turbulence
earth.turbsize = 1
earth.wavesize = 0
moon.grens( 0 ) = 0
moon.filldiffuse black , white , red , red ,red , red , red , red
moon.fillgrens 1,1,1,1,1,1,1,1
moon.kleurmax = 1
moon.scale = d3d( .1 , .1 , .1 )
moon.mattype = turbulence
moon.turbsize = 1
moon.wavesize = 0
mars.filldiffuse red , yellow , red , red , red , red , red , red
mars.fillgrens 1,1,1,1,1,1,1,1
mars.kleurmax = 1
mars.scale = d3d( .1 , .1 , .1 )
mars.mattype = turbulence
mars.turbsize = 1
mars.wavesize = 0
jupiter.filldiffuse red / 2 , red , yellow , white / 2 , white , white , red , red
jupiter.fillgrens .5,.6,.7,.9,1,1,1,1
jupiter.kleurmax = 5
jupiter.scale = d3d( 1 , .5 , 1 )
jupiter.mattype = turbulence or wave
jupiter.wavesize = 1 / 10
jupiter.turbsize = 10
neptune.grens( 0 ) = 0
neptune.filldiffuse blue , white , white , white , red , red , red , red
neptune.fillgrens .9 , 1 ,1,1,1,1,1,1
neptune.kleurmax = 1
neptune.scale = d3d( 1 , 1 , 1 )
neptune.mattype = turbulence ''or wave
neptune.wavesize = 0 ''1 / 5
neptune.turbsize = 1 ''0
sub test
spheretel = 0
link 1 , 0,0,0 , 0,0,0 , xyz , 0
addsphere 0,0,0 , 200 , jupiter
dim as integer i
for i = 0 to 10
link 1 , 0,0,0 , i*36,0,0 , xyz , 0
addsphere 350,0,0 , 70 , earth
next i
dim as d3d o , d
dim as double x , y
for x = -winx / 2 to winx / 2
for y = -winy / 2 to winy / 2
o = d3d( 0 , 0 , -1000 )
d = d3d( x , y , 1000 )
pset ( winx / 2 + x , winy / 2 - y ) _
, pixel( o , d ).tocolor()
next y
next x
end sub
cls
paint ( 1 , 1 ) , rgb( 127 , 127 , 127 )
test
''bsave "earth.bmp" , 0
sleep