|
Post by bluatigro on Dec 29, 2019 17:30:11 GMT
another try ad raytracing
error :
i only get a black square
so the code does not find the white sphere
any help is welkome
WindowWidth = DisplayWidth
WindowHeight = DisplayHeight
global winx , winy
winx = WindowWidth
winy = WindowHeight
global uit.x,uit.y,uit.z
global black,red,green,yellow
global blue,magenta,cyan,white
black=rgb(0,0,0)
red=rgb(255,0,0)
green=rgb(0,255,0)
yellow=rgb(255,255,0)
blue=rgb(0,0,255)
magenta=rgb(255,255,0)
cyan=rgb(0,255,255)
white=rgb(255,255,255)
dim sph(100,20)
global s.x,s.y,s.z,s.d,s.d2
global s.diffuse.r,s.diffuse.g,s.diffuse.b
global s.reflect
global infinity : infinity = 1e9
s.x = 0
s.y = 1
s.z = 2
s.d = 3
s.d2 = 4
s.diffuse.r = 5
s.diffuse.g = 6
s.diffuse.b = 7
s.reflect = 8
nomainwin
open "ray 0.1" for graphics as #m
#m "trapclose [quit]"
sphtel = 0
call sphere 0,0,0 , 60 , white , .5
for x = -100 to 100
for y = -100 to 100
scan
call ray 0,0,-1000 , x,y,1000 , 1
call pixel x,y , uit.x,uit.y,uit.z
next y
next x
notice "ready"
wait
[quit]
close #m
end
sub pixel x , y , r , g , b
r = int( r * 256 ) and 255
g = int( g * 256 ) and 255
b = int( b * 256 ) and 255
#m "goto " ; winx / 2 + x ; " " ; winy / 2 - y
#m "down"
#m "color " ; r ; " " ; g ; " " ; b
#m "set " ; winx / 2 + x ; " " ; winy / 2 - y
#m "up"
end sub
sub ray ox,oy,oz , dx,dy,dz,dept
low = infinity
sphno = -1
for i = 0 to sphtel
dist = sphere.hit(i,ox,oy,oz,dx,dy,dz)
if dist < low then
low = dist
sphno = i
end if
next i
if sphno = -1 then
r = 0
g = 0
b = 0
else
r = sph(sphno,s.diffuse.r)
g = sph(sphno,s.diffuse.g)
b = sph(sphno,s.diffuse.b)
''d-o
call vmin dx,dy,dz , ox,oy,oz
call vuit x,y,z
''normalize( d - o )
call vdiv x,y,z , lenght( x,y,z )
call vuit x,y,z
''point=v*dist
call vmul x,y,z , dist
call vuit x,y,z
''normal=point-sphere.centre
call vmin x,y,z _
, sph(sphno,s.x),sph(sphno,s.y),sph(sphno,s.z)
call vuit x,y,z
''normalize( normal )
call vdiv x,y,z , lenght( x,y,z )
call vuit x,y,z
''getangle( normalize(normal) , sunlight )
a = getangle( x,y,z , -5,10,-5 )
''shadowing sphere
call vmul r,g,b , cos(a)/2+.5
call vuit r,g,b
end if
''put output in uit vector
uit.x = r
uit.y = g
uit.z = b
end sub
sub sphere x,y,z , d , kl , flect
sph( sphtel , s.x ) = x
sph( sphtel , s.y ) = y
sph( sphtel , s.z ) = z
sph( sphtel , s.d ) = d
sph( sphtel , s.d2 ) = d * d
r = ( int( kl ) and 255 ) / 256
g = ( int( kl / 256 ) and 255 ) / 256
b = ( int( kl / 256 ^ 2 ) and 255 ) / 256
sph( sphtel , s.r ) = r
sph( sphtel , s.g ) = g
sph( sphtel , s.b ) = b
sph( sphtel , s.reflection ) = flect
sphtel = sphtel + 1
end sub
function rgb( r , g , b )
rgb = r + g * 256 + b * 256 ^ 2
end function
function sphere.hit( no , ox,oy,oz, dx,dy,dz )
call vmin ox,oy,oz _
, sph(no,s.x),sph(no,s.y),sph(no,s.z)
tx=uit.x:ty=uit.y:tz=uit.z
a = dot( dx,dy,dz , dx,dy,dz )
b = 2 * dot( tx,ty,tz , dx,dy,dz )
c = dot( tx,ty,tz , tx,ty,tz ) - sph(no,s.d2)
disc = b ^ 2 - 4 * a * c
uit = infinity
if disc >= 0 then
e = sqr( disc )
demon = 2 * a
t = ( 0 - b - e ) / demon
if t > 1e-9 then
uit = t
end if
t = ( 0 - b + e ) / demon
if t > 1e-9 then
uit = t
end if
end if
sphere.hit = uit
end function
sub vuit byref x,byref y, byref z
x = uit.x
y = uit.y
z = uit.z
end sub
sub vadd x1,y1,z1 , x2,y2,z2
''uit = v1 + v2
uit.x = x1 + x2
uit.y = y1 + y2
uit.z = z1 + z2
end sub
sub vmin x1,y1,z1 , x2,y2,z2
''uit = v1 - v2
uit.x = x1 - x2
uit.y = y1 - y2
uit.z = z1 - z2
end sub
sub vmul x1,y1,z1 , d
''uit = v1 * d
uit.x = x1 * d
uit.y = y1 * d
uit.z = z1 * d
end sub
sub vdiv x1,y1,z1 , d
''uit = v1 / d
uit.x = x1 / d
uit.y = y1 / d
uit..z = z1 / d
end sub
sub mirror x,y,z, nx,ny,nz
xz = atn( nx / nz )
yz = atn( ny / nz )
call rotate nx , nz , xz
call rotate x , z , xz
call rotate y , z , yz
z = 0 - z
call rotate y , z , 0 - yz
call rotate x , z , 0 - xz
uit.x = x
uit.y = y
uit.z = z
end sub
sub rotate byref k, byref l,radians
s = sin( radians )
c = cos( radians )
hk = k * c - l * s
hl = k * s + l * c
k = hk
l = hl
end sub
function getangle( x1,y1,z1 , x2,y2,z2 )
l1 = lenght( x1,y1,z1 )
l2 = lenght( x2,y2,z2 )
d = dot( x1,y1,z1 , x2,y2,z2 )
getangle = acs( d / ( l1 * l2 ) )
end function
function lenght( x,y,z )
''uit = | v |
lenght = sqr( dot( x,y,z , x,y,z ) )
end function
function dot( a,b,c , d,e,f )
dot = a*d + b*e + c*f
end function
|
|
|
Post by tsh73 on Dec 30, 2019 7:58:12 GMT
Hello bluatigro I found two probably errors one is in sub vdiv x1,y1,z1 , d there are line with two dots uit..z = z1 / d - it just don't work Second is that in sub ray ox,oy,oz , dx,dy,dz,dept block r = sph(sphno,s.diffuse.r) g = sph(sphno,s.diffuse.g) b = sph(sphno,s.diffuse.b)
always returns 0 because these places in array are not set. I have no idea what should be there, but setting r,g,b all to 255 produces this Probably not what supposed to be but better then nothing
|
|
|
Post by Rod on Dec 30, 2019 9:49:12 GMT
In the sphere sub you were using the wrong array pointers s.r should be s.diffuse.r ?
sub sphere x,y,z , d , kl , flect
sph( sphtel , s.x ) = x
sph( sphtel , s.y ) = y
sph( sphtel , s.z ) = z
sph( sphtel , s.d ) = d
sph( sphtel , s.d2 ) = d * d
r = ( int( kl ) and 255 ) / 256
g = ( int( kl / 256 ) and 255 ) / 256
b = ( int( kl / 256 ^ 2 ) and 255 ) / 256
sph( sphtel , s.diffuse.r ) = r
sph( sphtel , s.diffuse.g ) = g
sph( sphtel , s.diffuse.b ) = b
sph( sphtel , s.reflect ) = flect
sphtel = sphtel + 1
end sub
That gets a dull circle, Anatoly's fix is much better looking. Also s.reflect not s.reflection
|
|
|
Post by bluatigro on Dec 30, 2019 14:32:56 GMT
update : got the shading good now
error ? : i dont see my white sphere in the blue one reflected
WindowWidth = DisplayWidth WindowHeight = DisplayHeight global winx , winy winx = WindowWidth winy = WindowHeight global uit.x,uit.y,uit.z global black,red,green,yellow global blue,magenta,cyan,white black=rgb(0,0,0) red=rgb(255,0,0) green=rgb(0,255,0) yellow=rgb(255,255,0) blue=rgb(0,0,255) magenta=rgb(255,255,0) cyan=rgb(0,255,255) white=rgb(255,255,255) dim sph(100,20) global s.x,s.y,s.z,s.d,s.d2 global s.diffuse.r,s.diffuse.g,s.diffuse.b global s.reflect , sphtel global infinity : infinity = 1e9 s.x = 0 s.y = 1 s.z = 2 s.d = 3 s.d2 = 4 s.diffuse.r = 5 s.diffuse.g = 6 s.diffuse.b = 7 s.reflect = 8 nomainwin open "ray 0.1" for graphics as #m #m "trapclose [quit]" sphtel = 0 call sphere 50,0,0 , 40 , white , 0 call sphere -50,0,0 , 40 , blue , .5 for x = -100 to 100 for y = -100 to 100 scan call ray 0,0,-1000 , x,y,1000 , 7 call vuit r,g,b call pixel x,y , r,g,b next y next x notice "ready" wait [quit] close #m end sub pixel x , y , r , g , b r = int( r * 256 ) and 255 g = int( g * 256 ) and 255 b = int( b * 256 ) and 255 #m "goto " ; winx / 2 + x ; " " ; winy / 2 - y #m "down" #m "color " ; r ; " " ; g ; " " ; b #m "set " ; winx / 2 + x ; " " ; winy / 2 - y #m "up" end sub sub ray ox,oy,oz , dx,dy,dz,dept low = infinity sphno = -1 for i = 0 to sphtel dist = sphere.hit(i,ox,oy,oz,dx,dy,dz) if dist < low then low = dist sphno = i end if next i if sphno = -1 or dept < 0 then r = 0 g = 0 b = 0 else r = sph(sphno,s.diffuse.r) g = sph(sphno,s.diffuse.g) b = sph(sphno,s.diffuse.b) ''hit point is ? call vmul dx,dy,dz , low call vuit dx,dy,dz call vadd ox,oy,oz , dx,dy,dz call vuit px,py,pz ''normal=p-sphere.centre call vmin px,py,pz , sph(sphno,s.x),sph(sphno,s.y),sph(sphno,s.z) call vuit nx,ny,nz ''normalize( normal ) call vdiv nx,ny,nz , lenght( nx,ny,nz ) call vuit nx,ny,nz ''getangle( normalize(normal) , sunlight ) a = getangle( nx,ny,nz , -5,10,5 ) ''shadowing sphere call vmul r,g,b , cos(a)/2+.5 call vuit r,g,b if sph(sphno,s.reflect)>1e-5 then call mirror dx,dy,dz , nx,ny,nz call vuit dx,dy,dz call ray px,py,pz , dx,dy,dz , dept - 1 call vuit tr,tg,tb call vmin tr,tg,tb , r,g,b call vuit tr,tg,tb call vmul tr,th,tb , sph(sphno,s.reflect) call vuit tr,tg,tb call vadd r,g,b , tr,tg,tb call vuit r,g,b end if end if ''put output in uit vector uit.x = r uit.y = g uit.z = b end sub sub sphere x,y,z , d , kl , reflect sph( sphtel , s.x ) = x sph( sphtel , s.y ) = y sph( sphtel , s.z ) = z sph( sphtel , s.d ) = d sph( sphtel , s.d2 ) = d * d r = ( int( kl ) and 255 ) / 256 g = ( int( kl / 256 ) and 255 ) / 256 b = ( int( kl / 256 ^ 2 ) and 255 ) / 256 sph( sphtel , s.diffuse.r ) = r sph( sphtel , s.diffuse.g ) = g sph( sphtel , s.diffuse.b ) = b sph( sphtel , s.reflect ) = reflect sphtel = sphtel + 1 end sub function rgb( r , g , b ) rgb = r + g * 256 + b * 256 ^ 2 end function function sphere.hit( no , ox,oy,oz, dx,dy,dz ) call vmin ox,oy,oz , sph(no,s.x),sph(no,s.y),sph(no,s.z) call vuit tx,ty,tz a = dot( dx,dy,dz , dx,dy,dz ) b = 2 * dot( tx,ty,tz , dx,dy,dz ) c = dot( tx,ty,tz , tx,ty,tz ) - sph(no,s.d2) disc = b ^ 2 - 4 * a * c uit = infinity if disc >= 0 then e = sqr( disc ) demon = 2 * a t = ( 0 - b - e ) / demon if t > 1e-9 then uit = t end if t = ( 0 - b + e ) / demon if t > 1e-9 then uit = t end if end if sphere.hit = uit end function sub vuit byref x,byref y, byref z x = uit.x y = uit.y z = uit.z end sub sub vadd x1,y1,z1 , x2,y2,z2 ''uit = v1 + v2 uit.x = x1 + x2 uit.y = y1 + y2 uit.z = z1 + z2 end sub sub vmin x1,y1,z1 , x2,y2,z2 ''uit = v1 - v2 uit.x = x1 - x2 uit.y = y1 - y2 uit.z = z1 - z2 end sub sub vmul x1,y1,z1 , d ''uit = v1 * d uit.x = x1 * d uit.y = y1 * d uit.z = z1 * d end sub sub vdiv x1,y1,z1 , d ''uit = v1 / d if d = 0 then d = 0.0001 uit.x = x1 / d uit.y = y1 / d uit.z = z1 / d end sub sub mirror x,y,z, nx,ny,nz if nz <> 0 then xz = atn( nx / nz ) yz = atn( ny / nz ) end if call rotate nx , nz , xz call rotate x , z , xz call rotate y , z , yz z = 0 - z call rotate y , z , 0 - yz call rotate x , z , 0 - xz uit.x = x uit.y = y uit.z = z end sub sub rotate byref k, byref l,radians s = sin( radians ) c = cos( radians ) hk = k * c - l * s hl = k * s + l * c k = hk l = hl end sub function getangle( x1,y1,z1 , x2,y2,z2 ) l1 = lenght( x1,y1,z1 ) + 0.0001 l2 = lenght( x2,y2,z2 ) + 0.0001 d = dot( x1,y1,z1 , x2,y2,z2 ) getangle = acs( d / ( l1 * l2 ) ) end function function lenght( x,y,z ) ''uit = | v | lenght = sqr( dot( x,y,z , x,y,z ) ) end function function dot( a,b,c , d,e,f ) dot = a*d + b*e + c*f end function
|
|
|
Post by Rod on Dec 30, 2019 20:29:43 GMT
well the second sphere isn't drawn well, there is a slight tinge of reflection in the white sphere. Color code or angle of deflection after first hit must be wrong.
|
|
|
Post by Rod on Dec 31, 2019 12:40:23 GMT
I found some old code that raytraces spheres. I like what Bluatigro is doing I hope he gets his engine further than mine. Spheres are the easiest object to work with. You can do planes and cones, you can also have mirror surfaces. They always take a long time to draw. In the early days some computers took days to complete a high speck raytrace. I use the word raytrace to describe this coding. Doom style raycasting is a completely different technique.
What Bluatigro is doing is creating a three dimensional digital scene, then shining a light on it. The three dimensional world is actually just xyz points and the rays are vectors moving through these three dimensional points. So a vector would have a deltaX a deltaY and a deltaZ That way we can send rays from the light source into our eye. In fact we start by casting a ray from our eye or "camera" into the scene, when it hits an object we call that an intersect and from that point we start casting a ray of light from the light source to the intersect. To get the shadow we keep the ray going beyond the intersect till it hits something else. There we darken the image. Each object has a color and reflectivity which is all used to decide on the color displayed for the intersect. The intersect code is recursive till it runs out of distance.
This code creates a classic display of a room with spheres in it. The room is actually five massive spheres for the walls, floor and ceiling. There are a bunch of tutorials to seek out if the subject interests you. I hope Bluatigro can get us up and running with mirrors and planes.
nomainwin 'constants to access the point arrays global X,Y,Z,R,Red,Green,Blue,Xp,Yp,DistToScreen,maxObjects X=0 Y=1 Z=2 R=3 Red=4 Green=5 Blue=6
'the world is 24x24 units '0,0 is centre of the world '-12 far left 12 far right '12 top -12 bottom 'objects are specified in world units 'rays are specified in world units 'pixel coordinates are converted by 'dividing the world width by the screen width 'and the world height by the screen height 'this gives a per pixel world increment value
ScrXLeft=-12 ScrXRight=12 ScrYTop=-12 ScrYBottom=12 ImgX=800 'pixel width of screen ImgY=600 'pixel height of screen ScrX=2*ScrXRight/ImgX 'per pixel world increment value ScrY=2*ScrYBottom/ImgY
'Calculate how much space windows borders take 'Anatoly's tip WindowWidth = 200 WindowHeight = 200 open "Ajusting..." for graphics_nsb as #1 #1, "home ; down ; posxy w h" w=200-2*w : h = 200-2*h 'w and h now contain the number of pixels 'the Windows scheme/theme takes close #1 WindowWidth = ImgX+w WindowHeight = ImgY+h UpperLeftX = int((DisplayWidth-WindowWidth)/2) UpperLeftY = int((DisplayHeight-WindowHeight)/2) open "Raytrace" for graphics_nsb as #1 #1 "down ; fill 192 192 192 ; trapclose [quit]"
'sphere data x,y,z,radius,color 'three spheres ,red green and blue 'evenly spaced around centre of screen 'z order front to back blue, green, red
'there are five massive spheres positioned 'all round the edges and to the rear to create walls
maxObjects=7 dim sp(maxObjects,6) sp(0,X)=0 sp(0,Y)=0 sp(0,Z)=5 sp(0,R)=4 sp(0,Red)=255 sp(0,Green)=0 sp(0,Blue)=0 sp(1,X)=-6 sp(1,Y)=0 sp(1,Z)=5 sp(1,R)=2 sp(1,Red)=0 sp(1,Green)=255 sp(1,Blue)=0 sp(2,X)=6 sp(2,Y)=0 sp(2,Z)=2 sp(2,R)=2 sp(2,Red)=0 sp(2,Green)=0 sp(2,Blue)=255 sp(3,X)=-36 sp(3,Y)=0 sp(3,Z)=20 sp(3,R)=26 sp(3,Red)=64 sp(3,Green)=128 sp(3,Blue)=255 sp(4,X)=36 sp(4,Y)=0 sp(4,Z)=20 sp(4,R)=26 sp(4,Red)=64 sp(4,Green)=128 sp(4,Blue)=255 sp(5,X)=0 sp(5,Y)=-36 sp(5,Z)=20 sp(5,R)=26 sp(5,Red)=64 sp(5,Green)=128 sp(5,Blue)=25 sp(6,X)=0 sp(6,Y)=36 sp(6,Z)=20 sp(6,R)=26 sp(6,Red)=64 sp(6,Green)=128 sp(6,Blue)=25 sp(7,X)=0 sp(7,Y)=0 sp(7,Z)=36 sp(7,R)=24 sp(7,Red)=128 sp(7,Green)=128 sp(7,Blue)=128
'point origin of camera 'centre screen, 24 world units back from the image plane cam(X)=0 cam(Y)=0 cam(Z)=-24
'point origin of light source lit(X)=12 lit(Y)=5 lit(Z)=-10
'now cast a ray through every pixel on the screen for Xp=0 to ImgX for Yp=0 to ImgY scan
'point0, the camera x,y,z o(X)=cam(X) 'world x camera 0 o(Y)=cam(Y) 'world y camera 0 o(Z)=cam(Z) 'world z camera -10
'point1, the screen x,y,z 'which is ScrXLeft (-12) + .5 * ScrX, the per pixel world increment value 'to which we add xp * ScrX to give world x in world units r(X)=ScrXLeft+.5*ScrX+Xp*ScrX 'world x r(Y)=ScrYTop+.5*ScrY+Yp*ScrY 'world y r(Z)=0 'world z image plane 0
'flat parrallell ray no perspective 'o(X)=r(X) 'o(Y)=r(Y) 'o(Z)=-10
'subtract point0 from point1 to get vector direction d() d(X)=r(X)-o(X) d(Y)=r(Y)-o(Y) d(Z)=r(Z)-o(Z)
'normalize it by dividing by its length to make a unit vector ie it sums to 1 l=sqr(d(X)*d(X)+d(Y)*d(Y)+d(Z)*d(Z)) d(X)=d(X)/l d(Y)=d(Y)/l d(Z)=d(Z)/l DistToScreen=l
'go look for an intersect null=raySphereIntersect() next 'y next 'x
wait
[quit] close #1 end
function raySphereIntersect() maxdist=1000000 for o=0 to maxObjects b=2*d(X)*(o(X)-sp(o,X))+2*d(Y)*(o(Y)-sp(o,Y))+2*d(Z)*(o(Z)-sp(o,Z)) c=(o(X)-sp(o,X))^2+(o(Y)-sp(o,Y))^2+(o(Z)-sp(o,Z))^2-sp(o,R)^2 d = b * b - 4 * c if d>0 then t=(b*-1 - sqr(b*b-4*c))/2 if t>DistToScreen then 'store the shortest intersect of all sphere intersects if t<maxdist then maxdist=t : id=o end if end if next if maxdist<1000000 then
'establish the sphere surface intersect point i(X)=o(X)+d(X)*maxdist i(Y)=o(Y)+d(Y)*maxdist i(Z)=o(Z)+d(Z)*maxdist
'get unit normal vector from sphere centre to surface intersect n(X)=(i(X)-sp(id,X))/sp(id,R) n(Y)=(i(Y)-sp(id,Y))/sp(id,R) n(Z)=(i(Z)-sp(id,Z))/sp(id,R)
'get the unit normal vector from sphere surface intersect to the light l(X)=lit(X)-i(X) l(Y)=lit(Y)-i(Y) l(Z)=lit(Z)-i(Z) l=sqr(l(X)*l(X)+l(Y)*l(Y)+l(Z)*l(Z)) l(X)=l(X)/l l(Y)=l(Y)/l l(Z)=l(Z)/l 'the dot product of these vectors gives an indication of the light color=n(X)*l(X)+n(Y)*l(Y)+n(Z)*l(Z)
'cast a ray from intersect to the light to check for shadow 'we have done most of the ray prep 'point0 is the intersect point1 is the light 'so l() is our ray direction, point1-point0, normalized shadow=1 for o=0 to maxObjects if o<>id then 'check all other spheres not the one we are currently considering b=2*l(X)*(i(X)-sp(o,X))+2*l(Y)*(i(Y)-sp(o,Y))+2*l(Z)*(i(Z)-sp(o,Z)) c=(i(X)-sp(o,X))^2+(i(Y)-sp(o,Y))^2+(i(Z)-sp(o,Z))^2-sp(o,R)^2 d = b * b - 4 * c if d>0 then t=(b*-1 - sqr(b*b-4*c))/2 if d>0 and t>0 then shadow=.8 : exit for end if next
'add some ambient light if color < .5 then color = .5
'color the pixel #1 "color ";sp(id,Red)*color*shadow;" ";sp(id,Green)*color*shadow;" ";sp(id,Blue)*color*shadow;" ; set ";Xp;" ";Yp
end if
end function
|
|
|
Post by bluatigro on Dec 31, 2019 16:18:49 GMT
update :
triangle stuf added light added
rem : i turned the relection off for sub mirror i need a atan2(x,y) function [ i think ]
error : where is my red triangle ?
WindowWidth = DisplayWidth WindowHeight = DisplayHeight global winx , winy winx = WindowWidth winy = WindowHeight global uit.x,uit.y,uit.z global black,red,green,yellow global blue,magenta,cyan,white black=rgb(0,0,0) red=rgb(255,0,0) green=rgb(0,255,0) yellow=rgb(255,255,0) blue=rgb(0,0,255) magenta=rgb(255,255,0) cyan=rgb(0,255,255) white=rgb(255,255,255) dim sph(100,8),tri(100,15) global s.x,s.y,s.z,s.d,s.d2 global s.diffuse.r,s.diffuse.g,s.diffuse.b global s.reflect , sphtel global t.x1,t.y1,t.z1,t.x2,t.y2,t.z2,t.x3,t.y3,t.z3,t.nx,t.ny,t.nz global t.diffuse.r,t.diffuse.g,t.diffuse.b global t.reflect , tritel global light.x,light.y,light.z global infinity : infinity = 1e9 s.x = 0 s.y = 1 s.z = 2 s.d = 3 s.d2 = 4 s.diffuse.r = 5 s.diffuse.g = 6 s.diffuse.b = 7 s.reflect = 8 t.x1=0 t.y1=1 t.z1=2 t.x2=3 t.y2=4 t.z2=5 t.x3=6 t.y3=7 t.z3=8 t.nx=9 t.ny=10 t.nz=11 t.difusse.r=12 t.diffuse.g=13 t.diffuse.b=14 t.reflect=15 nomainwin open "ray 0.1" for graphics as #m #m "trapclose [quit]" sphtel = 0 tritel = 0 call light -5,10,5 call sphere 50,0,0 , 40 , white , 0 call sphere -50,0,0 , 40 , blue , 0 call triangle 0,40,0 , -20,-32,0 , 20,-32,0 , red , 0 for x = -100 to 100 for y = -100 to 100 scan call ray 0,0,-1000 , x,y,1000 , 7 call vuit r,g,b call pixel x,y , r,g,b next y next x notice "ready" wait [quit] close #m end sub light x , y , z light.x=x light.y=y light.z=z end sub function tri.hit(n , ox,oy,oz , dx,dy,dz ) call vmin tri(n,t.x2),tri(n,t.y2),tri(n,t.z2) _ , tri(n,t.x1),tri(n,t.y1),tri(n,t.z1) call vuit e1.x,e1.y,e1.z call vmin tri(n,t.x3),tri(n,t.y3),tri(n,t.z3) _ , tri(n,t.x1),tri(n,t.y1),tri(n,t.z1) call vuit e2.x,e2.y,e2.z call cross dx,dy,dz , e2.x,e2.y,e2.z call vuit px,py,pz a = dot( e1.x,e1.y,e1.z , px,py,pz ) if abs( a ) < 1e-9 then uit = infinity else f = 1 / a call vmin ox,oy,oz _ , tri(n,t.x1),tri(n,t.y1),tri(n,t.z1) call vuit sx,sy,sz u = f * dot( sx,sy,sz , px,py,pz ) if 0 > u or u > 1 then uit = infinity else call cross sx,sy,sz , e1.x,e1.y,e1.z call vuit qx,qy,qz v = f * dot( dx,dy,dz , qx,qy,qz ) if v < 0 or v + u > 1 then uit = infinity else uit = f * dot( e2.x,e2.y,e2.z , qx,qy,qz ) end if end if end if
tri.hit = uit end function sub triangle x1,y1,z1 , x2,y2,z2 , x3,y3,z3 , kl , reflect tri(tritel,t.x1)=x1 tri(tritel,t.y1)=x1 tri(tritel,t.z1)=x1 tri(tritel,t.x2)=x1 tri(tritel,t.y2)=x1 tri(tritel,t.z2)=x1 tri(tritel,t.x3)=x1 tri(tritel,t.y3)=x1 tri(tritel,t.z3)=x1 call cross x2-x1,y2-y1,z2-z1 , x3-x1,y3-y1,z3-z1 call vuit nx,ny,nz call vdiv nx,ny,nz , lenght( nx,ny,nz ) tri(tritel,t.nx)=nz tri(tritel,t.ny)=ny tri(tritel,t.nz)=nz r = ( int( kl ) and 255 ) / 256 g = ( int( kl / 256 ) and 255 ) / 256 b = ( int( kl / 256 ^ 2 ) and 255 ) / 256 tri( tritel , t.diffuse.r ) = r tri( tritel , t.diffuse.g ) = g tri( tritel , t.diffuse.b ) = b tri( tritel , t.reflect ) = reflect tritel = tritel + 1 end sub sub cross x1,y1,z1 , x2,y2,z2 uit.x = y1 * z2 - y2 * z1 uit.y = z1 * x2 - z2 * x1 uit.z = x1 * y2 - x2 * y1 end sub sub pixel x , y , r , g , b r = int( r * 256 ) and 255 g = int( g * 256 ) and 255 b = int( b * 256 ) and 255 #m "goto " ; winx / 2 + x ; " " ; winy / 2 - y #m "down" #m "color " ; r ; " " ; g ; " " ; b #m "set " ; winx / 2 + x ; " " ; winy / 2 - y #m "up" end sub sub ray ox,oy,oz , dx,dy,dz,dept low = infinity sphno = -1 for i = 0 to sphtel dist = sphere.hit(i,ox,oy,oz,dx,dy,dz) if dist < low then low = dist sphno = i end if next i tlow = infinity trino = -1 for i = 0 to tritel dist = tri.hit(i,ox,oy,oz,dx,dy,dz) if dist < tlow then tlow = dist trino = i end if next i if ( sphno = -1 and trino = -1 ) or dept < 0 then r = 0 g = 0 b = 0 else if low < tlow then r = sph(sphno,s.diffuse.r) g = sph(sphno,s.diffuse.g) b = sph(sphno,s.diffuse.b) ''hit point is ? call vmul dx,dy,dz , low call vuit dx,dy,dz call vadd ox,oy,oz , dx,dy,dz call vuit px,py,pz ''normal=p-sphere.centre call vmin px,py,pz , sph(sphno,s.x),sph(sphno,s.y),sph(sphno,s.z) call vuit nx,ny,nz ''normalize( normal ) call vdiv nx,ny,nz , lenght( nx,ny,nz ) call vuit nx,ny,nz ''getangle( normalize(normal) , sunlight ) a = getangle( nx,ny,nz _ , light.x,light.y,light.z ) ''shadowing sphere call vmul r,g,b , cos(a)/2+.5 call vuit r,g,b if sph(sphno,s.reflect)>1e-5 then call mirror dx,dy,dz , nx,ny,nz call vuit dx,dy,dz call ray px,py,pz , dx,dy,dz , dept - 1 call vuit tr,tg,tb call vmin tr,tg,tb , r,g,b call vuit tr,tg,tb call vmul tr,th,tb , sph(sphno,s.reflect) call vuit tr,tg,tb call vadd r,g,b , tr,tg,tb call vuit r,g,b end if else r = tri(trino,t.diffuse.r) g = tri(trino,t.difusse.g) b = tri(trino,t.diffuse.b) nx = tri(trino,t.nx) ny = tri(trino,t.ny) nz = tri(trino,t.nz) a = getangle( nx,ny,nz _ , light.x,light.y,light.z ) ''shadowing sphere call vmul r,g,b , cos(a)/2+.5 call vuit r,g,b end if end if ''put output in uit vector uit.x = r uit.y = g uit.z = b end sub sub sphere x,y,z , d , kl , reflect sph( sphtel , s.x ) = x sph( sphtel , s.y ) = y sph( sphtel , s.z ) = z sph( sphtel , s.d ) = d sph( sphtel , s.d2 ) = d * d r = ( int( kl ) and 255 ) / 256 g = ( int( kl / 256 ) and 255 ) / 256 b = ( int( kl / 256 ^ 2 ) and 255 ) / 256 sph( sphtel , s.diffuse.r ) = r sph( sphtel , s.diffuse.g ) = g sph( sphtel , s.diffuse.b ) = b sph( sphtel , s.reflect ) = reflect sphtel = sphtel + 1 end sub function rgb( r , g , b ) rgb = r + g * 256 + b * 256 ^ 2 end function function sphere.hit( no , ox,oy,oz, dx,dy,dz ) call vmin ox,oy,oz , sph(no,s.x),sph(no,s.y),sph(no,s.z) call vuit tx,ty,tz a = dot( dx,dy,dz , dx,dy,dz ) b = 2 * dot( tx,ty,tz , dx,dy,dz ) c = dot( tx,ty,tz , tx,ty,tz ) - sph(no,s.d2) disc = b ^ 2 - 4 * a * c uit = infinity if disc >= 0 then e = sqr( disc ) demon = 2 * a t = ( 0 - b - e ) / demon if t > 1e-9 then uit = t end if t = ( 0 - b + e ) / demon if t > 1e-9 then uit = t end if end if sphere.hit = uit end function sub vuit byref x,byref y, byref z x = uit.x y = uit.y z = uit.z end sub sub vadd x1,y1,z1 , x2,y2,z2 ''uit = v1 + v2 uit.x = x1 + x2 uit.y = y1 + y2 uit.z = z1 + z2 end sub sub vmin x1,y1,z1 , x2,y2,z2 ''uit = v1 - v2 uit.x = x1 - x2 uit.y = y1 - y2 uit.z = z1 - z2 end sub sub vmul x1,y1,z1 , d ''uit = v1 * d uit.x = x1 * d uit.y = y1 * d uit.z = z1 * d end sub sub vdiv x1,y1,z1 , d ''uit = v1 / d if d = 0 then d = 0.0001 uit.x = x1 / d uit.y = y1 / d uit.z = z1 / d end sub sub mirror x,y,z, nx,ny,nz if nz <> 0 then xz = atn( nx / nz ) yz = atn( ny / nz ) end if call rotate nx , nz , xz call rotate x , z , xz call rotate y , z , yz z = 0 - z call rotate y , z , 0 - yz call rotate x , z , 0 - xz uit.x = x uit.y = y uit.z = z end sub sub rotate byref k, byref l,radians s = sin( radians ) c = cos( radians ) hk = k * c - l * s hl = k * s + l * c k = hk l = hl end sub function getangle( x1,y1,z1 , x2,y2,z2 ) l1 = lenght( x1,y1,z1 ) + 0.0001 l2 = lenght( x2,y2,z2 ) + 0.0001 d = dot( x1,y1,z1 , x2,y2,z2 ) getangle = acs( d / ( l1 * l2 ) ) end function function lenght( x,y,z ) ''uit = | v | lenght = sqr( dot( x,y,z , x,y,z ) ) end function function dot( a,b,c , d,e,f ) dot = a*d + b*e + c*f end function
|
|
|
Post by Rod on Jan 1, 2020 10:03:22 GMT
In your triangle sub you are setting everything to the same point x1, not x1 x2 x3 z1 z2 etc
|
|
|
Post by bluatigro on Jan 1, 2020 13:03:04 GMT
Rod : thanks for spotting that update : point system added for triangles error : my triangles get on top of spheres the red one looks yellow the green one gets black [ i think the shadow is to stark ]
WindowWidth = DisplayWidth WindowHeight = DisplayHeight global winx , winy winx = WindowWidth winy = WindowHeight global uit.x,uit.y,uit.z global black,red,green,yellow global blue,magenta,cyan,white black=rgb(0,0,0) red=rgb(255,0,0) green=rgb(0,255,0) yellow=rgb(255,255,0) blue=rgb(0,0,255) magenta=rgb(255,255,0) cyan=rgb(0,255,255) white=rgb(255,255,255) dim sph(100,8),tri(100,15),pnt(255,2) global s.x,s.y,s.z,s.d,s.d2 global s.diffuse.r,s.diffuse.g,s.diffuse.b global s.reflect , sphtel global t.x1,t.y1,t.z1,t.x2,t.y2,t.z2,t.x3,t.y3,t.z3,t.nx,t.ny,t.nz global t.diffuse.r,t.diffuse.g,t.diffuse.b global t.reflect , tritel global light.x,light.y,light.z global p.x,p.y,p.z global infinity : infinity = 1e9 s.x = 0 s.y = 1 s.z = 2 s.d = 3 s.d2 = 4 s.diffuse.r = 5 s.diffuse.g = 6 s.diffuse.b = 7 s.reflect = 8 t.x1=0 t.y1=1 t.z1=2 t.x2=3 t.y2=4 t.z2=5 t.x3=6 t.y3=7 t.z3=8 t.nx=9 t.ny=10 t.nz=11 t.difusse.r=12 t.diffuse.g=13 t.diffuse.b=14 t.reflect=15 p.x=0 p.y=1 p.z=2 nomainwin open "ray 0.1" for graphics as #m #m "trapclose [quit]" sphtel = 0 tritel = 0 call light -5,10,5 call sphere 50,0,0 , 40 , white , 0 call sphere -50,0,0 , 40 , blue , 0 call setpoint 0 , 0,100,0 call setpoint 1 , -86,-100,0 call setpoint 2 , 86,-100,0 call setpoint 3 , 0,0,-86 call tri 0 , 1 , 2 , blue , 0 call tri 0 , 1 , 3 , yellow , 0 call tri 0 , 2 , 3 , green , 0 call tri 1 , 2 , 3 , red , 0 for x = -100 to 100 for y = -100 to 100 scan call ray 0,0,-1000 , x,y,1000 , 7 call vuit r,g,b call pixel x,y , r,g,b next y next x notice "ready" wait [quit] close #m end sub setpoint no , x,y,z pnt(no,p.x)=x pnt(no,p.y)=y pnt(no,p.z)=z end sub sub tri a , b , c , kl , reflect call triangle pnt(a,p.x),pnt(a,p.y),pnt(a,p.z) _ , pnt(b,p.x),pnt(b,p.y),pnt(b,p.z) _ , pnt(c,p.x),pnt(c,p.y),pnt(c,p.z) _ , kl , reflect end sub sub light x , y , z light.x=x light.y=y light.z=z end sub function tri.hit(n , ox,oy,oz , dx,dy,dz ) call vmin tri(n,t.x2),tri(n,t.y2),tri(n,t.z2) _ , tri(n,t.x1),tri(n,t.y1),tri(n,t.z1) call vuit e1.x,e1.y,e1.z call vmin tri(n,t.x3),tri(n,t.y3),tri(n,t.z3) _ , tri(n,t.x1),tri(n,t.y1),tri(n,t.z1) call vuit e2.x,e2.y,e2.z call cross dx,dy,dz , e2.x,e2.y,e2.z call vuit px,py,pz a = dot( e1.x,e1.y,e1.z , px,py,pz ) if abs( a ) < 1e-9 then uit = infinity else f = 1 / a call vmin ox,oy,oz _ , tri(n,t.x1),tri(n,t.y1),tri(n,t.z1) call vuit sx,sy,sz u = f * dot( sx,sy,sz , px,py,pz ) if 0 > u or u > 1 then uit = infinity else call cross sx,sy,sz , e1.x,e1.y,e1.z call vuit qx,qy,qz v = f * dot( dx,dy,dz , qx,qy,qz ) if v < 0 or v + u > 1 then uit = infinity else uit = f * dot( e2.x,e2.y,e2.z , qx,qy,qz ) end if end if end if
tri.hit = uit end function sub triangle x1,y1,z1 , x2,y2,z2 , x3,y3,z3 , kl , reflect tri(tritel,t.x1)=x1 tri(tritel,t.y1)=y1 tri(tritel,t.z1)=z1 tri(tritel,t.x2)=x2 tri(tritel,t.y2)=y2 tri(tritel,t.z2)=z2 tri(tritel,t.x3)=x3 tri(tritel,t.y3)=y3 tri(tritel,t.z3)=z3 call cross x2-x1,y2-y1,z2-z1 , x3-x1,y3-y1,z3-z1 call vuit nx,ny,nz call vdiv nx,ny,nz , lenght( nx,ny,nz ) tri(tritel,t.nx)=nz tri(tritel,t.ny)=ny tri(tritel,t.nz)=nz r = ( int( kl ) and 255 ) / 256 g = ( int( kl / 256 ) and 255 ) / 256 b = ( int( kl / 256 ^ 2 ) and 255 ) / 256 tri( tritel , t.diffuse.r ) = r tri( tritel , t.diffuse.g ) = g tri( tritel , t.diffuse.b ) = b tri( tritel , t.reflect ) = reflect tritel = tritel + 1 end sub sub cross x1,y1,z1 , x2,y2,z2 uit.x = y1 * z2 - y2 * z1 uit.y = z1 * x2 - z2 * x1 uit.z = x1 * y2 - x2 * y1 end sub sub pixel x , y , r , g , b r = int( r * 256 ) and 255 g = int( g * 256 ) and 255 b = int( b * 256 ) and 255 #m "goto " ; winx / 2 + x ; " " ; winy / 2 - y #m "down" #m "color " ; r ; " " ; g ; " " ; b #m "set " ; winx / 2 + x ; " " ; winy / 2 - y #m "up" end sub sub ray ox,oy,oz , dx,dy,dz,dept low = infinity sphno = -1 for i = 0 to sphtel dist = sphere.hit(i,ox,oy,oz,dx,dy,dz) if dist < low then low = dist sphno = i end if next i tlow = infinity trino = -1 for i = 0 to tritel dist = tri.hit(i,ox,oy,oz,dx,dy,dz) if dist < tlow then tlow = dist trino = i end if next i if ( sphno = -1 and trino = -1 ) or dept < 0 then r = 0 g = 0 b = 0 else if low < tlow then r = sph(sphno,s.diffuse.r) g = sph(sphno,s.diffuse.g) b = sph(sphno,s.diffuse.b) ''hit point is ? call vmul dx,dy,dz , low call vuit dx,dy,dz call vadd ox,oy,oz , dx,dy,dz call vuit px,py,pz ''normal=p-sphere.centre call vmin px,py,pz , sph(sphno,s.x),sph(sphno,s.y),sph(sphno,s.z) call vuit nx,ny,nz ''normalize( normal ) call vdiv nx,ny,nz , lenght( nx,ny,nz ) call vuit nx,ny,nz ''getangle( normalize(normal) , sunlight ) a = getangle( nx,ny,nz _ , light.x,light.y,light.z ) ''shadowing sphere call vmul r,g,b , cos(a)/2+.5 call vuit r,g,b if sph(sphno,s.reflect)>1e-5 then call mirror dx,dy,dz , nx,ny,nz call vuit dx,dy,dz call ray px,py,pz , dx,dy,dz , dept - 1 call vuit tr,tg,tb call vmin tr,tg,tb , r,g,b call vuit tr,tg,tb call vmul tr,th,tb , sph(sphno,s.reflect) call vuit tr,tg,tb call vadd r,g,b , tr,tg,tb call vuit r,g,b end if else r = tri(trino,t.diffuse.r) g = tri(trino,t.difusse.g) b = tri(trino,t.diffuse.b) nx = tri(trino,t.nx) ny = tri(trino,t.ny) nz = tri(trino,t.nz) a = getangle( nx,ny,nz _ , light.x,light.y,light.z ) ''shadowing sphere call vmul r,g,b , cos(a)/2+.5 call vuit r,g,b end if end if ''put output in uit vector uit.x = r uit.y = g uit.z = b end sub sub sphere x,y,z , d , kl , reflect sph( sphtel , s.x ) = x sph( sphtel , s.y ) = y sph( sphtel , s.z ) = z sph( sphtel , s.d ) = d sph( sphtel , s.d2 ) = d * d r = ( int( kl ) and 255 ) / 256 g = ( int( kl / 256 ) and 255 ) / 256 b = ( int( kl / 256 ^ 2 ) and 255 ) / 256 sph( sphtel , s.diffuse.r ) = r sph( sphtel , s.diffuse.g ) = g sph( sphtel , s.diffuse.b ) = b sph( sphtel , s.reflect ) = reflect sphtel = sphtel + 1 end sub function rgb( r , g , b ) rgb = r + g * 256 + b * 256 ^ 2 end function function sphere.hit( no , ox,oy,oz, dx,dy,dz ) call vmin ox,oy,oz , sph(no,s.x),sph(no,s.y),sph(no,s.z) call vuit tx,ty,tz a = dot( dx,dy,dz , dx,dy,dz ) b = 2 * dot( tx,ty,tz , dx,dy,dz ) c = dot( tx,ty,tz , tx,ty,tz ) - sph(no,s.d2) disc = b ^ 2 - 4 * a * c uit = infinity if disc >= 0 then e = sqr( disc ) demon = 2 * a t = ( 0 - b - e ) / demon if t > 1e-9 then uit = t end if t = ( 0 - b + e ) / demon if t > 1e-9 then uit = t end if end if sphere.hit = uit end function sub vuit byref x,byref y, byref z x = uit.x y = uit.y z = uit.z end sub sub vadd x1,y1,z1 , x2,y2,z2 ''uit = v1 + v2 uit.x = x1 + x2 uit.y = y1 + y2 uit.z = z1 + z2 end sub sub vmin x1,y1,z1 , x2,y2,z2 ''uit = v1 - v2 uit.x = x1 - x2 uit.y = y1 - y2 uit.z = z1 - z2 end sub sub vmul x1,y1,z1 , d ''uit = v1 * d uit.x = x1 * d uit.y = y1 * d uit.z = z1 * d end sub sub vdiv x1,y1,z1 , d ''uit = v1 / d if d = 0 then d = 0.0001 uit.x = x1 / d uit.y = y1 / d uit.z = z1 / d end sub sub mirror x,y,z, nx,ny,nz if nz <> 0 then xz = atn( nx / nz ) yz = atn( ny / nz ) end if call rotate nx , nz , xz call rotate x , z , xz call rotate y , z , yz z = 0 - z call rotate y , z , 0 - yz call rotate x , z , 0 - xz uit.x = x uit.y = y uit.z = z end sub sub rotate byref k, byref l,radians s = sin( radians ) c = cos( radians ) hk = k * c - l * s hl = k * s + l * c k = hk l = hl end sub function getangle( x1,y1,z1 , x2,y2,z2 ) l1 = lenght( x1,y1,z1 ) + 0.0001 l2 = lenght( x2,y2,z2 ) + 0.0001 d = dot( x1,y1,z1 , x2,y2,z2 ) getangle = acs( d / ( l1 * l2 ) ) end function function lenght( x,y,z ) ''uit = | v | lenght = sqr( dot( x,y,z , x,y,z ) ) end function function dot( a,b,c , d,e,f ) dot = a*d + b*e + c*f end function
|
|
|
Post by bluatigro on Jan 1, 2020 13:37:49 GMT
update : light 3x [ red , green and blue ]
error : only the 'red' , 'blue' and 'green' triangle shoot be visable the spheres shoot be partly before the triangles
rem : i like the result whit the spheres
WindowWidth = DisplayWidth WindowHeight = DisplayHeight global winx , winy winx = WindowWidth winy = WindowHeight global uit.x,uit.y,uit.z global black,red,green,yellow global blue,magenta,cyan,white black=rgb(0,0,0) red=rgb(255,0,0) green=rgb(0,255,0) yellow=rgb(255,255,0) blue=rgb(0,0,255) magenta=rgb(255,255,0) cyan=rgb(0,255,255) white=rgb(255,255,255) dim sph(100,8),tri(100,15),pnt(255,2) global s.x,s.y,s.z,s.d,s.d2 global s.diffuse.r,s.diffuse.g,s.diffuse.b global s.reflect , sphtel global t.x1,t.y1,t.z1,t.x2,t.y2,t.z2,t.x3,t.y3,t.z3,t.nx,t.ny,t.nz global t.diffuse.r,t.diffuse.g,t.diffuse.b global t.reflect , tritel global l.r.x,l.r.y,l.r.z global l.g.x,l.g.y,l.g.z global l.b.x,l.b.y,l.b.z global p.x,p.y,p.z global infinity : infinity = 1e9 s.x = 0 s.y = 1 s.z = 2 s.d = 3 s.d2 = 4 s.diffuse.r = 5 s.diffuse.g = 6 s.diffuse.b = 7 s.reflect = 8 t.x1=0 t.y1=1 t.z1=2 t.x2=3 t.y2=4 t.z2=5 t.x3=6 t.y3=7 t.z3=8 t.nx=9 t.ny=10 t.nz=11 t.difusse.r=12 t.diffuse.g=13 t.diffuse.b=14 t.reflect=15 p.x=0 p.y=1 p.z=2 nomainwin open "ray 1.5" for graphics as #m #m "trapclose [quit]" sphtel = 0 tritel = 0 call light -5,10,5 , 5,10,5 , 0,-10,5 call sphere 50,0,0 , 60 , white , 0 call sphere -50,0,0 , 60 , white , 0 call setpoint 0 , 0,100,0 call setpoint 1 , -86,-100,0 call setpoint 2 , 86,-100,0 call setpoint 3 , 0,0,-86 call tri 0 , 1 , 2 , white , 0 call tri 0 , 1 , 3 , white , 0 call tri 0 , 2 , 3 , white , 0 call tri 1 , 2 , 3 , white , 0 for x = -100 to 100 for y = -100 to 100 scan call ray 0,0,-1000 , x,y,1000 , 7 call vuit r,g,b call pixel x,y , r,g,b next y next x notice "ready" wait [quit] close #m end sub setpoint no , x,y,z pnt(no,p.x)=x pnt(no,p.y)=y pnt(no,p.z)=z end sub sub tri a , b , c , kl , reflect call triangle pnt(a,p.x),pnt(a,p.y),pnt(a,p.z) _ , pnt(b,p.x),pnt(b,p.y),pnt(b,p.z) _ , pnt(c,p.x),pnt(c,p.y),pnt(c,p.z) _ , kl , reflect end sub sub light rx,ry,rz , gx,gy,gz , bx,by,bz l.r.x=rx l.r.y=ry l.r.z=rz l.g.x=gx l.g.y=gy l.g.z=gz l.b.x=bx l.b.y=by l.b.z=bz end sub function tri.hit(n , ox,oy,oz , dx,dy,dz ) call vmin tri(n,t.x2),tri(n,t.y2),tri(n,t.z2) _ , tri(n,t.x1),tri(n,t.y1),tri(n,t.z1) call vuit e1x,e1y,e1z call vmin tri(n,t.x3),tri(n,t.y3),tri(n,t.z3) _ , tri(n,t.x1),tri(n,t.y1),tri(n,t.z1) call vuit e2x,e2y,e2z call cross dx,dy,dz , e2x,e2y,e2z call vuit px,py,pz a = dot( e1x,e1y,e1z , px,py,pz ) if abs( a ) < 1e-9 then uit = infinity else f = 1 / a call vmin ox,oy,oz _ , tri(n,t.x1),tri(n,t.y1),tri(n,t.z1) call vuit sx,sy,sz u = f * dot( sx,sy,sz , px,py,pz ) if 0 > u or u > 1 then uit = infinity else call cross sx,sy,sz , e1x,e1y,e1z call vuit qx,qy,qz v = f * dot( dx,dy,dz , qx,qy,qz ) if v < 0 or v + u > 1 then uit = infinity else uit = f * dot( e2x,e2y,e2z , qx,qy,qz ) end if end if end if
tri.hit = uit end function sub triangle x1,y1,z1 , x2,y2,z2 , x3,y3,z3 , diffuse , reflect tri(tritel,t.x1)=x1 tri(tritel,t.y1)=y1 tri(tritel,t.z1)=z1 tri(tritel,t.x2)=x2 tri(tritel,t.y2)=y2 tri(tritel,t.z2)=z2 tri(tritel,t.x3)=x3 tri(tritel,t.y3)=y3 tri(tritel,t.z3)=z3 call cross x2-x1,y2-y1,z2-z1 , x3-x1,y3-y1,z3-z1 call vuit nx,ny,nz call vdiv nx,ny,nz , lenght( nx,ny,nz ) tri(tritel,t.nx)=nz tri(tritel,t.ny)=ny tri(tritel,t.nz)=nz r = ( int( diffuse ) and 255 ) / 256 g = ( int( diffuse / 256 ) and 255 ) / 256 b = ( int( diffuse / 256 ^ 2 ) and 255 ) / 256 tri( tritel , t.diffuse.r ) = r tri( tritel , t.diffuse.g ) = g tri( tritel , t.diffuse.b ) = b tri( tritel , t.reflect ) = reflect tritel = tritel + 1 end sub sub cross x1,y1,z1 , x2,y2,z2 uit.x = y1 * z2 - y2 * z1 uit.y = z1 * x2 - z2 * x1 uit.z = x1 * y2 - x2 * y1 end sub sub pixel x , y , r , g , b r = int( r * 256 ) and 255 g = int( g * 256 ) and 255 b = int( b * 256 ) and 255 #m "goto " ; winx / 2 + x ; " " ; winy / 2 - y #m "down" #m "color " ; r ; " " ; g ; " " ; b #m "set " ; winx / 2 + x ; " " ; winy / 2 - y #m "up" end sub sub ray ox,oy,oz , dx,dy,dz,dept low = infinity sphno = -1 for i = 0 to sphtel dist = sphere.hit(i,ox,oy,oz,dx,dy,dz) if dist < low then low = dist sphno = i end if next i tlow = infinity trino = -1 for i = 0 to tritel dist = tri.hit(i,ox,oy,oz,dx,dy,dz) if dist < tlow then tlow = dist trino = i end if next i if ( sphno = -1 and trino = -1 ) or dept < 0 then r = 0 g = 0 b = 0 else if low < tlow then r = sph(sphno,s.diffuse.r) g = sph(sphno,s.diffuse.g) b = sph(sphno,s.diffuse.b) ''hit point is ? call vmul dx,dy,dz , low call vuit dx,dy,dz call vadd ox,oy,oz , dx,dy,dz call vuit px,py,pz ''normal=p-sphere.centre call vmin px,py,pz , sph(sphno,s.x),sph(sphno,s.y),sph(sphno,s.z) call vuit nx,ny,nz ''normalize( normal ) call vdiv nx,ny,nz , lenght( nx,ny,nz ) call vuit nx,ny,nz ''getangle( normalize(normal) , sunlight ) ar = getangle( nx,ny,nz , l.r.x,l.r.y,l.r.z ) ag = getangle( nx,ny,nz , l.g.x,l.g.y,l.g.z ) ab = getangle( nx,ny,nz , l.b.x,l.b.y,l.b.z ) ''shadowing sphere r = r * cos(ar)/2+.5 g = g * cos(ag)/2+.5 b = b * cos(ab)/2+.5 if sph(sphno,s.reflect)>1e-5 then call mirror dx,dy,dz , nx,ny,nz call vuit dx,dy,dz call ray px,py,pz , dx,dy,dz , dept - 1 call vuit tr,tg,tb call vmin tr,tg,tb , r,g,b call vuit tr,tg,tb call vmul tr,th,tb , sph(sphno,s.reflect) call vuit tr,tg,tb call vadd r,g,b , tr,tg,tb call vuit r,g,b end if else r = tri(trino,t.diffuse.r) g = tri(trino,t.difusse.g) b = tri(trino,t.diffuse.b) nx = tri(trino,t.nx) ny = tri(trino,t.ny) nz = tri(trino,t.nz) ''getangle( normalize(normal) , sunlight ) ar = getangle( nx,ny,nz , l.r.x,l.r.y,l.r.z ) ag = getangle( nx,ny,nz , l.g.x,l.g.y,l.g.z ) ab = getangle( nx,ny,nz , l.b.x,l.b.y,l.b.z ) ''shadowing triangle r = r * cos(ar)/2+.5 g = g * cos(ag)/2+.5 b = b * cos(ab)/2+.5
end if end if ''put output in uit vector uit.x = r uit.y = g uit.z = b end sub sub sphere x,y,z , d , diffuse , reflect sph( sphtel , s.x ) = x sph( sphtel , s.y ) = y sph( sphtel , s.z ) = z sph( sphtel , s.d ) = d sph( sphtel , s.d2 ) = d * d r = ( int( diffuse ) and 255 ) / 256 g = ( int( diffuse / 256 ) and 255 ) / 256 b = ( int( diffuse / 256 ^ 2 ) and 255 ) / 256 sph( sphtel , s.diffuse.r ) = r sph( sphtel , s.diffuse.g ) = g sph( sphtel , s.diffuse.b ) = b sph( sphtel , s.reflect ) = reflect sphtel = sphtel + 1 end sub function rgb( r , g , b ) rgb = r + g * 256 + b * 256 ^ 2 end function function sphere.hit( no , ox,oy,oz, dx,dy,dz ) call vmin ox,oy,oz , sph(no,s.x),sph(no,s.y),sph(no,s.z) call vuit tx,ty,tz a = dot( dx,dy,dz , dx,dy,dz ) b = 2 * dot( tx,ty,tz , dx,dy,dz ) c = dot( tx,ty,tz , tx,ty,tz ) - sph(no,s.d2) disc = b ^ 2 - 4 * a * c uit = infinity if disc >= 0 then e = sqr( disc ) demon = 2 * a t = ( 0 - b - e ) / demon if t > 1e-9 then uit = t end if t = ( 0 - b + e ) / demon if t > 1e-9 then uit = t end if end if sphere.hit = uit end function sub vuit byref x,byref y, byref z x = uit.x y = uit.y z = uit.z end sub sub vadd x1,y1,z1 , x2,y2,z2 ''uit = v1 + v2 uit.x = x1 + x2 uit.y = y1 + y2 uit.z = z1 + z2 end sub sub vmin x1,y1,z1 , x2,y2,z2 ''uit = v1 - v2 uit.x = x1 - x2 uit.y = y1 - y2 uit.z = z1 - z2 end sub sub vmul x1,y1,z1 , d ''uit = v1 * d uit.x = x1 * d uit.y = y1 * d uit.z = z1 * d end sub sub vdiv x1,y1,z1 , d ''uit = v1 / d if d = 0 then d = 0.0001 uit.x = x1 / d uit.y = y1 / d uit.z = z1 / d end sub sub mirror x,y,z, nx,ny,nz if nz <> 0 then xz = atn( nx / nz ) yz = atn( ny / nz ) end if call rotate nx , nz , xz call rotate x , z , xz call rotate y , z , yz z = 0 - z call rotate y , z , 0 - yz call rotate x , z , 0 - xz uit.x = x uit.y = y uit.z = z end sub sub rotate byref k, byref l,radians s = sin( radians ) c = cos( radians ) hk = k * c - l * s hl = k * s + l * c k = hk l = hl end sub function getangle( x1,y1,z1 , x2,y2,z2 ) l1 = lenght( x1,y1,z1 ) + 0.0001 l2 = lenght( x2,y2,z2 ) + 0.0001 d = dot( x1,y1,z1 , x2,y2,z2 ) getangle = acs( d / ( l1 * l2 ) ) end function function lenght( x,y,z ) ''uit = | v | lenght = sqr( dot( x,y,z , x,y,z ) ) end function function dot( a,b,c , d,e,f ) dot = a*d + b*e + c*f end function
|
|
|
Post by bluatigro on Jan 1, 2020 16:07:14 GMT
update : 3d engine added
WindowWidth = DisplayWidth WindowHeight = DisplayHeight global winx , winy , pi winx = WindowWidth winy = WindowHeight pi = atn( 1 ) * 4 global uit.x,uit.y,uit.z global black,red,green,yellow global blue,magenta,cyan,white black=rgb(0,0,0) red=rgb(255,0,0) green=rgb(0,255,0) yellow=rgb(255,255,0) blue=rgb(0,0,255) magenta=rgb(255,255,0) cyan=rgb(0,255,255) white=rgb(255,255,255) dim sph(100,8),tri(100,15),pnt(255,2) dim v(in(26,3,3)) , sk(64,3) global rotx,roty,rotz,trans,temp,temp2 rotx=21:roty=22:rotz=23:trans=24:temp=25:temp2=26 global xyz,xzy,yxz,yzx,zxy,zyx,matrixno xyz=0:xzy=1:yxz=2:yzx=3:zxy=4:zyx=5 global s.x,s.y,s.z,s.d,s.d2 global s.diffuse.r,s.diffuse.g,s.diffuse.b global s.reflect , sphtel global t.x1,t.y1,t.z1,t.x2,t.y2,t.z2,t.x3,t.y3,t.z3,t.nx,t.ny,t.nz global t.diffuse.r,t.diffuse.g,t.diffuse.b global t.reflect , tritel global l.r.x,l.r.y,l.r.z global l.g.x,l.g.y,l.g.z global l.b.x,l.b.y,l.b.z global p.x,p.y,p.z global infinity : infinity = 1e9 s.x=0:s.y=1:s.z=2:s.d = 3:s.d2 = 4 s.diffuse.r = 5:s.diffuse.g = 6:s.diffuse.b = 7 s.reflect = 8 t.x1=0:t.y1=1:t.z1=2 t.x2=3:t.y2=4:t.z2=5 t.x3=6:t.y3=7:t.z3=8 t.nx=9:t.ny=10:t.nz=11 t.difusse.r=12:t.diffuse.g=13:t.diffuse.b=14 t.reflect=15 p.x=0:p.y=1:p.z=2 nomainwin open "ray 1.5" for graphics as #m #m "trapclose [quit]" call init3degine sphtel = 0 tritel = 0 call light -5,10,5 , 5,10,5 , 0,-10,5 call link 1 , 0,0,0 , 0,0,0 , xyz , 0 call sphere 50,0,0 , 60 , white , 0 call sphere -50,0,0 , 60 , white , 0 call setpoint 0 , 0,80,0 call setpoint 1 , -80,-80,0 call setpoint 2 , 80,-80,0 call setpoint 3 , 0,0,-80 call tri 0 , 1 , 2 , white , 0 call tri 0 , 1 , 3 , white , 0 call tri 0 , 2 , 3 , white , 0 call tri 1 , 2 , 3 , white , 0 for x = -100 to 100 for y = -100 to 100 scan call ray 0,0,-1000 , x,y,1000 , 7 call vuit r,g,b call pixel x,y , r,g,b next y next x notice "ready" wait [quit] close #m end sub setpoint no , x,y,z call spot x,y,z pnt(no,p.x)=x pnt(no,p.y)=y pnt(no,p.z)=z end sub sub tri a , b , c , kl , reflect call triangle pnt(a,p.x),pnt(a,p.y),pnt(a,p.z) _ , pnt(b,p.x),pnt(b,p.y),pnt(b,p.z) _ , pnt(c,p.x),pnt(c,p.y),pnt(c,p.z) _ , kl , reflect end sub sub light rx,ry,rz , gx,gy,gz , bx,by,bz l.r.x=rx l.r.y=ry l.r.z=rz l.g.x=gx l.g.y=gy l.g.z=gz l.b.x=bx l.b.y=by l.b.z=bz end sub function tri.hit(n , ox,oy,oz , dx,dy,dz ) call vmin tri(n,t.x2),tri(n,t.y2),tri(n,t.z2) _ , tri(n,t.x1),tri(n,t.y1),tri(n,t.z1) call vuit e1x,e1y,e1z call vmin tri(n,t.x3),tri(n,t.y3),tri(n,t.z3) _ , tri(n,t.x1),tri(n,t.y1),tri(n,t.z1) call vuit e2x,e2y,e2z call cross dx,dy,dz , e2x,e2y,e2z call vuit px,py,pz a = dot( e1x,e1y,e1z , px,py,pz ) if abs( a ) < 1e-9 then uit = infinity else f = 1 / a call vmin ox,oy,oz _ , tri(n,t.x1),tri(n,t.y1),tri(n,t.z1) call vuit sx,sy,sz u = f * dot( sx,sy,sz , px,py,pz ) if 0 > u or u > 1 then uit = infinity else call cross sx,sy,sz , e1x,e1y,e1z call vuit qx,qy,qz v = f * dot( dx,dy,dz , qx,qy,qz ) if v < 0 or v + u > 1 then uit = infinity else uit = f * dot( e2x,e2y,e2z , qx,qy,qz ) end if end if end if
tri.hit = uit end function sub triangle x1,y1,z1 , x2,y2,z2 , x3,y3,z3 , diffuse , reflect tri(tritel,t.x1)=x1 tri(tritel,t.y1)=y1 tri(tritel,t.z1)=z1 tri(tritel,t.x2)=x2 tri(tritel,t.y2)=y2 tri(tritel,t.z2)=z2 tri(tritel,t.x3)=x3 tri(tritel,t.y3)=y3 tri(tritel,t.z3)=z3 call cross x2-x1,y2-y1,z2-z1 , x3-x1,y3-y1,z3-z1 call vuit nx,ny,nz call vdiv nx,ny,nz , lenght( nx,ny,nz ) tri(tritel,t.nx)=nz tri(tritel,t.ny)=ny tri(tritel,t.nz)=nz r = ( int( diffuse ) and 255 ) / 256 g = ( int( diffuse / 256 ) and 255 ) / 256 b = ( int( diffuse / 256 ^ 2 ) and 255 ) / 256 tri( tritel , t.diffuse.r ) = r tri( tritel , t.diffuse.g ) = g tri( tritel , t.diffuse.b ) = b tri( tritel , t.reflect ) = reflect tritel = tritel + 1 end sub sub cross x1,y1,z1 , x2,y2,z2 uit.x = y1 * z2 - y2 * z1 uit.y = z1 * x2 - z2 * x1 uit.z = x1 * y2 - x2 * y1 end sub sub pixel x , y , r , g , b r = int( r * 256 ) and 255 g = int( g * 256 ) and 255 b = int( b * 256 ) and 255 #m "goto " ; winx / 2 + x ; " " ; winy / 2 - y #m "down" #m "color " ; r ; " " ; g ; " " ; b #m "set " ; winx / 2 + x ; " " ; winy / 2 - y #m "up" end sub sub ray ox,oy,oz , dx,dy,dz,dept low = infinity sphno = -1 for i = 0 to sphtel dist = sphere.hit(i,ox,oy,oz,dx,dy,dz) if dist < low then low = dist sphno = i end if next i tlow = infinity trino = -1 for i = 0 to tritel dist = tri.hit(i,ox,oy,oz,dx,dy,dz) if dist < tlow then tlow = dist trino = i end if next i if ( sphno = -1 and trino = -1 ) or dept < 0 then r = 0 g = 0 b = 0 else if low < tlow then r = sph(sphno,s.diffuse.r) g = sph(sphno,s.diffuse.g) b = sph(sphno,s.diffuse.b) ''hit point is ? call vmul dx,dy,dz , low call vuit dx,dy,dz call vadd ox,oy,oz , dx,dy,dz call vuit px,py,pz ''normal=p-sphere.centre call vmin px,py,pz , sph(sphno,s.x),sph(sphno,s.y),sph(sphno,s.z) call vuit nx,ny,nz ''normalize( normal ) call vdiv nx,ny,nz , lenght( nx,ny,nz ) call vuit nx,ny,nz ''getangle( normalize(normal) , sunlight ) ar = getangle( nx,ny,nz , l.r.x,l.r.y,l.r.z ) ag = getangle( nx,ny,nz , l.g.x,l.g.y,l.g.z ) ab = getangle( nx,ny,nz , l.b.x,l.b.y,l.b.z ) ''shadowing sphere r = r * cos(ar)/2+.5 g = g * cos(ag)/2+.5 b = b * cos(ab)/2+.5 if sph(sphno,s.reflect)>1e-5 then call mirror dx,dy,dz , nx,ny,nz call vuit dx,dy,dz call ray px,py,pz , dx,dy,dz , dept - 1 call vuit tr,tg,tb call vmin tr,tg,tb , r,g,b call vuit tr,tg,tb call vmul tr,th,tb , sph(sphno,s.reflect) call vuit tr,tg,tb call vadd r,g,b , tr,tg,tb call vuit r,g,b end if else r = tri(trino,t.diffuse.r) g = tri(trino,t.difusse.g) b = tri(trino,t.diffuse.b) nx = tri(trino,t.nx) ny = tri(trino,t.ny) nz = tri(trino,t.nz) ''getangle( normalize(normal) , sunlight ) ar = getangle( nx,ny,nz , l.r.x,l.r.y,l.r.z ) ag = getangle( nx,ny,nz , l.g.x,l.g.y,l.g.z ) ab = getangle( nx,ny,nz , l.b.x,l.b.y,l.b.z ) ''shadowing triangle r = r * cos(ar)/2+.5 g = g * cos(ag)/2+.5 b = b * cos(ab)/2+.5
end if end if ''put output in uit vector uit.x = r uit.y = g uit.z = b end sub sub sphere x,y,z , d , diffuse , reflect call spot x,y,z sph( sphtel , s.x ) = x sph( sphtel , s.y ) = y sph( sphtel , s.z ) = z sph( sphtel , s.d ) = d sph( sphtel , s.d2 ) = d * d r = ( int( diffuse ) and 255 ) / 256 g = ( int( diffuse / 256 ) and 255 ) / 256 b = ( int( diffuse / 256 ^ 2 ) and 255 ) / 256 sph( sphtel , s.diffuse.r ) = r sph( sphtel , s.diffuse.g ) = g sph( sphtel , s.diffuse.b ) = b sph( sphtel , s.reflect ) = reflect sphtel = sphtel + 1 end sub function rgb( r , g , b ) rgb = r + g * 256 + b * 256 ^ 2 end function function sphere.hit( no , ox,oy,oz, dx,dy,dz ) call vmin ox,oy,oz , sph(no,s.x),sph(no,s.y),sph(no,s.z) call vuit tx,ty,tz a = dot( dx,dy,dz , dx,dy,dz ) b = 2 * dot( tx,ty,tz , dx,dy,dz ) c = dot( tx,ty,tz , tx,ty,tz ) - sph(no,s.d2) disc = b ^ 2 - 4 * a * c uit = infinity if disc >= 0 then e = sqr( disc ) demon = 2 * a t = ( 0 - b - e ) / demon if t > 1e-9 then uit = t end if t = ( 0 - b + e ) / demon if t > 1e-9 then uit = t end if end if sphere.hit = uit end function sub vuit byref x,byref y, byref z x = uit.x y = uit.y z = uit.z end sub sub vadd x1,y1,z1 , x2,y2,z2 ''uit = v1 + v2 uit.x = x1 + x2 uit.y = y1 + y2 uit.z = z1 + z2 end sub sub vmin x1,y1,z1 , x2,y2,z2 ''uit = v1 - v2 uit.x = x1 - x2 uit.y = y1 - y2 uit.z = z1 - z2 end sub sub vmul x1,y1,z1 , d ''uit = v1 * d uit.x = x1 * d uit.y = y1 * d uit.z = z1 * d end sub sub vdiv x1,y1,z1 , d ''uit = v1 / d if d = 0 then d = 0.0001 uit.x = x1 / d uit.y = y1 / d uit.z = z1 / d end sub sub mirror x,y,z, nx,ny,nz if nz <> 0 then xz = atn( nx / nz ) yz = atn( ny / nz ) end if call rotate nx , nz , xz call rotate x , z , xz call rotate y , z , yz z = 0 - z call rotate y , z , 0 - yz call rotate x , z , 0 - xz uit.x = x uit.y = y uit.z = z end sub sub rotate byref k, byref l,radians s = sin( radians ) c = cos( radians ) hk = k * c - l * s hl = k * s + l * c k = hk l = hl end sub function getangle( x1,y1,z1 , x2,y2,z2 ) l1 = lenght( x1,y1,z1 ) + 0.0001 l2 = lenght( x2,y2,z2 ) + 0.0001 d = dot( x1,y1,z1 , x2,y2,z2 ) getangle = acs( d / ( l1 * l2 ) ) end function function lenght( x,y,z ) ''uit = | v | lenght = sqr( dot( x,y,z , x,y,z ) ) end function function dot( a,b,c , d,e,f ) dot = a*d + b*e + c*f end function [3dengine] function rad( deg ) rad = deg * pi / 180 end function function in(n,x,y) in = n * 16 + x * 4 + y end function sub init3degine for i = 0 to 3 for j = 0 to 3 v(in(0,i,j))=0 next j v(in(0,i,i))=1 next i end sub sub copy uit , n for i = 0 to 3 for j = 0 to 3 v(in(uit,i,j))=v(in(n,i,j)) next j next i end sub sub mxm uit , a , b for i = 0 to 3 for j = 0 to 3 v(in(uit,i,j))=0 for k = 0 to 3 v(in(uit,i,j))=v(in(uit,i,j)) _ + v(in(a,i,k)) * v(in(b,k,j)) next k next j next i end sub sub mxmxm uit , a , b , c , p call mxm temp , a , b call mxm temp2 , temp , c call mxm temp , temp2 , trans call mxm temp2 , temp , p call copy uit , temp2 end sub sub link n , x,y,z , xz,xy,yz , ax , p if n < 1 or n > 20 then exit sub if p < 0 or p > 20 then exit sub if p = n then exit sub
call copy rotx , 0 call copy roty , 0 call copy rotz , 0 call copy trans , 0
v(in(rotx,1,1))=cos(rad(yz)) v(in(rotx,1,2))=0-sin(rad(yz)) v(in(rotx,2,1))=sin(rad(yz)) v(in(rotx,2,2))=cos(rad(yz))
v(in(roty,0,0))=cos(rad(yz)) v(in(roty,0,2))=0-sin(rad(yz)) v(in(roty,2,0))=sin(rad(yz)) v(in(roty,2,2))=cos(rad(yz))
v(in(rotz,1,1))=cos(rad(yz)) v(in(rotz,1,0))=sin(rad(yz)) v(in(rotz,0,1))=0-sin(rad(yz)) v(in(rotz,0,0))=cos(rad(yz))
v(in(trans,3,0))=x v(in(trans,3,1))=y v(in(trans,3,2))=z
select case ax case xyz call mxmxm n , rotx , roty , rotz , p case xzy call mxmxm n , rotx , rotz , roty , p case yxz call mxmxm n , roty , rotx , rotz , p case yzx call mxmxm n , roty , rotz , rotx , p case zxy call mxmxm n , rotz , rotx , roty , p case zyx call mxmxm n , rotz , roty , rotx , p case else end select matrixno = n end sub sub skelet lim , x , y , z if lim < 0 or lim > 64 then exit sub sk(lim,0)=x sk(lim,1)=y sk(lim,2)=z end sub sub child n , x , y , z , lim , ax , p if lim < 0 or lim > 64 then exit sub call link n , x , y , z _ , sk(lim,1),sk(lim,0),sk(lim,2),ax,p end sub sub spot byref x , byref y , byref z hx=x*v(in(matrixno,0,0)) _ +y*v(in(matrixno,1,0)) _ +z*v(in(matrixno,2,0)) _ + v(in(matrixno,3,0)) hy=x*v(in(matrixno,0,1)) _ +y*v(in(matrixno,1,1)) _ +z*v(in(matrixno,2,1)) _ + v(in(matrixno,3,1)) hz=x*v(in(matrixno,0,2)) _ +y*v(in(matrixno,1,2)) _ +z*v(in(matrixno,2,2)) _ + v(in(matrixno,3,2)) x=hx:y=hy:z=hz end sub
|
|
|
Post by bluatigro on Jan 1, 2020 17:12:54 GMT
update : atan2(x,y) added [ please check if it good ] for try at reflection rem : there can be a error in sub mirror [ please check ]
WindowWidth = DisplayWidth WindowHeight = DisplayHeight global winx , winy , pi winx = WindowWidth winy = WindowHeight pi = atn( 1 ) * 4 global uit.x,uit.y,uit.z global black,red,green,yellow global blue,magenta,cyan,white
black=rgb(0,0,0) red=rgb(255,0,0) green=rgb(0,255,0) yellow=rgb(255,255,0) blue=rgb(0,0,255) magenta=rgb(255,255,0) cyan=rgb(0,255,255) white=rgb(255,255,255) dim sph(100,8),tri(100,15),pnt(255,2) dim v(in(26,3,3)) , sk(64,3) global rotx,roty,rotz,trans,temp,temp2 rotx=21:roty=22:rotz=23:trans=24:temp=25:temp2=26 global xyz,xzy,yxz,yzx,zxy,zyx,matrixno xyz=0:xzy=1:yxz=2:yzx=3:zxy=4:zyx=5 global s.x,s.y,s.z,s.d,s.d2 global s.diffuse.r,s.diffuse.g,s.diffuse.b global s.reflect , sphtel global t.x1,t.y1,t.z1,t.x2,t.y2,t.z2,t.x3,t.y3,t.z3,t.nx,t.ny,t.nz global t.diffuse.r,t.diffuse.g,t.diffuse.b global t.reflect , tritel global l.r.x,l.r.y,l.r.z global l.g.x,l.g.y,l.g.z global l.b.x,l.b.y,l.b.z global p.x,p.y,p.z global infinity : infinity = 1e9 s.x=0:s.y=1:s.z=2:s.d = 3:s.d2 = 4 s.diffuse.r = 5:s.diffuse.g = 6:s.diffuse.b = 7 s.reflect = 8 t.x1=0:t.y1=1:t.z1=2 t.x2=3:t.y2=4:t.z2=5 t.x3=6:t.y3=7:t.z3=8 t.nx=9:t.ny=10:t.nz=11 t.difusse.r=12:t.diffuse.g=13:t.diffuse.b=14 t.reflect=15 p.x=0:p.y=1:p.z=2 nomainwin open "ray 2.0" for graphics as #m #m "trapclose [quit]" call init3degine sphtel = 0 tritel = 0 call light -5,10,5 , 5,10,5 , 0,-10,5 call link 1 , 0,0,0 , 0,0,0 , xyz , 0 call sphere 50,0,0 , 50 , rgb(99,99,99) , .5 call sphere -50,0,0 , 50 , white , 0 '' call setpoint 0 , 0,40,0 '' call setpoint 1 , -40,-40,0 '' call setpoint 2 , 40,-40,0 '' call setpoint 3 , 0,0,-40 '' call tri 0 , 1 , 2 , white , 0 '' call tri 0 , 1 , 3 , white , 0 '' call tri 0 , 2 , 3 , white , 0 '' call tri 1 , 2 , 3 , white , 0 for x = -150 to 150 for y = -80 to 80 scan call ray 0,0,-1000 , x,y,1000 , 7 call vuit r,g,b call pixel x,y , r,g,b next y next x notice "ready" wait [quit] close #m end function atan2( x , y ) if abs( x ) < 1e-9 then if y < 0 then uit = 0 - pi / 2 else uit = pi / 2 end if else if x > 0 then uit = atn( y / x ) else uit = pi + atn( y / x ) end if end if atan2 = uit end function sub setpoint no , x,y,z call spot x,y,z pnt(no,p.x)=x pnt(no,p.y)=y pnt(no,p.z)=z end sub sub tri a , b , c , kl , reflect call triangle pnt(a,p.x),pnt(a,p.y),pnt(a,p.z) _ , pnt(b,p.x),pnt(b,p.y),pnt(b,p.z) _ , pnt(c,p.x),pnt(c,p.y),pnt(c,p.z) _ , kl , reflect end sub sub light rx,ry,rz , gx,gy,gz , bx,by,bz l.r.x=rx l.r.y=ry l.r.z=rz l.g.x=gx l.g.y=gy l.g.z=gz l.b.x=bx l.b.y=by l.b.z=bz end sub function tri.hit(n , ox,oy,oz , dx,dy,dz ) call vmin tri(n,t.x2),tri(n,t.y2),tri(n,t.z2) _ , tri(n,t.x1),tri(n,t.y1),tri(n,t.z1) call vuit e1x,e1y,e1z call vmin tri(n,t.x3),tri(n,t.y3),tri(n,t.z3) _ , tri(n,t.x1),tri(n,t.y1),tri(n,t.z1) call vuit e2x,e2y,e2z call cross dx,dy,dz , e2x,e2y,e2z call vuit px,py,pz a = dot( e1x,e1y,e1z , px,py,pz ) if abs( a ) < 1e-9 then uit = infinity else f = 1 / a call vmin ox,oy,oz _ , tri(n,t.x1),tri(n,t.y1),tri(n,t.z1) call vuit sx,sy,sz u = f * dot( sx,sy,sz , px,py,pz ) if 0 > u or u > 1 then uit = infinity else call cross sx,sy,sz , e1x,e1y,e1z call vuit qx,qy,qz v = f * dot( dx,dy,dz , qx,qy,qz ) if v < 0 or v + u > 1 then uit = infinity else uit = f * dot( e2x,e2y,e2z , qx,qy,qz ) end if end if end if
tri.hit = uit end function sub triangle x1,y1,z1 , x2,y2,z2 , x3,y3,z3 , diffuse , reflect tri(tritel,t.x1)=x1 tri(tritel,t.y1)=y1 tri(tritel,t.z1)=z1 tri(tritel,t.x2)=x2 tri(tritel,t.y2)=y2 tri(tritel,t.z2)=z2 tri(tritel,t.x3)=x3 tri(tritel,t.y3)=y3 tri(tritel,t.z3)=z3 call cross x2-x1,y2-y1,z2-z1 , x3-x1,y3-y1,z3-z1 call vuit nx,ny,nz call vdiv nx,ny,nz , lenght( nx,ny,nz ) tri(tritel,t.nx)=nz tri(tritel,t.ny)=ny tri(tritel,t.nz)=nz r = ( int( diffuse ) and 255 ) / 256 g = ( int( diffuse / 256 ) and 255 ) / 256 b = ( int( diffuse / 256 ^ 2 ) and 255 ) / 256 tri( tritel , t.diffuse.r ) = r tri( tritel , t.diffuse.g ) = g tri( tritel , t.diffuse.b ) = b tri( tritel , t.reflect ) = reflect tritel = tritel + 1 end sub sub cross x1,y1,z1 , x2,y2,z2 uit.x = y1 * z2 - y2 * z1 uit.y = z1 * x2 - z2 * x1 uit.z = x1 * y2 - x2 * y1 end sub sub pixel x , y , r , g , b r = int( r * 256 ) and 255 g = int( g * 256 ) and 255 b = int( b * 256 ) and 255 #m "goto " ; winx / 2 + x ; " " ; winy / 2 - y #m "down" #m "color " ; r ; " " ; g ; " " ; b #m "set " ; winx / 2 + x ; " " ; winy / 2 - y #m "up" end sub sub ray ox,oy,oz , dx,dy,dz , dept low = infinity sphno = -1 for i = 0 to sphtel dist = sphere.hit(i,ox,oy,oz,dx,dy,dz) if dist < low then low = dist sphno = i end if next i tlow = infinity trino = -1 for i = 0 to tritel dist = tri.hit(i,ox,oy,oz,dx,dy,dz) if dist < tlow then tlow = dist trino = i end if next i if ( sphno = -1 and trino = -1 ) or dept < 0 then r = 0 g = 0 b = 0 else if low < tlow then r = sph(sphno,s.diffuse.r) g = sph(sphno,s.diffuse.g) b = sph(sphno,s.diffuse.b) ''hit point is ? call vmul dx,dy,dz , low call vuit dx,dy,dz call vadd ox,oy,oz , dx,dy,dz call vuit px,py,pz ''normal=p-sphere.centre call vmin px,py,pz , sph(sphno,s.x),sph(sphno,s.y),sph(sphno,s.z) call vuit nx,ny,nz ''normalize( normal ) call vdiv nx,ny,nz , lenght( nx,ny,nz ) call vuit nx,ny,nz ''getangle( normalize(normal) , sunlight ) ar = getangle( nx,ny,nz , l.r.x,l.r.y,l.r.z ) ag = getangle( nx,ny,nz , l.g.x,l.g.y,l.g.z ) ab = getangle( nx,ny,nz , l.b.x,l.b.y,l.b.z ) ''shadowing sphere r = r * cos(ar)/2+.5 g = g * cos(ag)/2+.5 b = b * cos(ab)/2+.5 if sph(sphno,s.reflect)>1e-5 then call mirror dx,dy,dz , nx,ny,nz call vuit dx,dy,dz call ray px,py,pz , dx,dy,dz , dept - 1 call vuit tr,tg,tb call vmin tr,tg,tb , r,g,b call vuit tr,tg,tb call vmul tr,tg,tb , sph(sphno,s.reflect) call vuit tr,tg,tb call vadd r,g,b , tr,tg,tb call vuit r,g,b end if else r = tri(trino,t.diffuse.r) g = tri(trino,t.difusse.g) b = tri(trino,t.diffuse.b) nx = tri(trino,t.nx) ny = tri(trino,t.ny) nz = tri(trino,t.nz) ''getangle( normalize(normal) , sunlight ) ar = getangle( nx,ny,nz , l.r.x,l.r.y,l.r.z ) ag = getangle( nx,ny,nz , l.g.x,l.g.y,l.g.z ) ab = getangle( nx,ny,nz , l.b.x,l.b.y,l.b.z ) ''shadowing triangle r = r * cos(ar)/2+.5 g = g * cos(ag)/2+.5 b = b * cos(ab)/2+.5
end if end if ''put output in uit vector uit.x = r uit.y = g uit.z = b end sub sub sphere x,y,z , d , diffuse , reflect call spot x,y,z sph( sphtel , s.x ) = x sph( sphtel , s.y ) = y sph( sphtel , s.z ) = z sph( sphtel , s.d ) = d sph( sphtel , s.d2 ) = d * d r = ( int( diffuse ) and 255 ) / 256 g = ( int( diffuse / 256 ) and 255 ) / 256 b = ( int( diffuse / 256 ^ 2 ) and 255 ) / 256 sph( sphtel , s.diffuse.r ) = r sph( sphtel , s.diffuse.g ) = g sph( sphtel , s.diffuse.b ) = b sph( sphtel , s.reflect ) = reflect sphtel = sphtel + 1 end sub function rgb( r , g , b ) rgb = r + g * 256 + b * 256 ^ 2 end function function sphere.hit( no , ox,oy,oz, dx,dy,dz ) call vmin ox,oy,oz , sph(no,s.x),sph(no,s.y),sph(no,s.z) call vuit tx,ty,tz a = dot( dx,dy,dz , dx,dy,dz ) b = 2 * dot( tx,ty,tz , dx,dy,dz ) c = dot( tx,ty,tz , tx,ty,tz ) - sph(no,s.d2) disc = b ^ 2 - 4 * a * c uit = infinity if disc >= 0 then e = sqr( disc ) demon = 2 * a t = ( 0 - b - e ) / demon if t > 1e-9 then uit = t end if t = ( 0 - b + e ) / demon if t > 1e-9 then uit = t end if end if sphere.hit = uit end function sub vuit byref x,byref y, byref z x = uit.x y = uit.y z = uit.z end sub sub vadd x1,y1,z1 , x2,y2,z2 ''uit = v1 + v2 uit.x = x1 + x2 uit.y = y1 + y2 uit.z = z1 + z2 end sub sub vmin x1,y1,z1 , x2,y2,z2 ''uit = v1 - v2 uit.x = x1 - x2 uit.y = y1 - y2 uit.z = z1 - z2 end sub sub vmul x1,y1,z1 , d ''uit = v1 * d uit.x = x1 * d uit.y = y1 * d uit.z = z1 * d end sub sub vdiv x1,y1,z1 , d ''uit = v1 / d if d = 0 then d = 0.0001 uit.x = x1 / d uit.y = y1 / d uit.z = z1 / d end sub sub mirror x,y,z, nx,ny,nz xz = atan2( nx , nz ) yz = atan2( ny , nz ) call rotate nx , nz , xz call rotate x , z , xz call rotate y , z , yz z = 0 - z call rotate y , z , 0 - yz call rotate x , z , 0 - xz uit.x = x uit.y = y uit.z = z end sub sub rotate byref k, byref l,radians s = sin( radians ) c = cos( radians ) hk = k * c - l * s hl = k * s + l * c k = hk l = hl end sub function getangle( x1,y1,z1 , x2,y2,z2 ) l1 = lenght( x1,y1,z1 ) + 0.0001 l2 = lenght( x2,y2,z2 ) + 0.0001 d = dot( x1,y1,z1 , x2,y2,z2 ) getangle = acs( d / ( l1 * l2 ) ) end function function lenght( x,y,z ) ''uit = | v | lenght = sqr( dot( x,y,z , x,y,z ) ) end function function dot( a,b,c , d,e,f ) dot = a*d + b*e + c*f end function [3dengine] function rad( deg ) rad = deg * pi / 180 end function function in(n,x,y) in = n * 16 + x * 4 + y end function sub init3degine for i = 0 to 3 for j = 0 to 3 v(in(0,i,j))=0 next j v(in(0,i,i))=1 next i end sub sub copy uit , n for i = 0 to 3 for j = 0 to 3 v(in(uit,i,j))=v(in(n,i,j)) next j next i end sub sub mxm uit , a , b for i = 0 to 3 for j = 0 to 3 v(in(uit,i,j))=0 for k = 0 to 3 v(in(uit,i,j))=v(in(uit,i,j)) _ + v(in(a,i,k)) * v(in(b,k,j)) next k next j next i end sub sub mxmxm uit , a , b , c , p call mxm temp , a , b call mxm temp2 , temp , c call mxm temp , temp2 , trans call mxm temp2 , temp , p call copy uit , temp2 end sub sub link n , x,y,z , xz,xy,yz , ax , p if n < 1 or n > 20 then exit sub if p < 0 or p > 20 then exit sub if p = n then exit sub
call copy rotx , 0 call copy roty , 0 call copy rotz , 0 call copy trans , 0
v(in(rotx,1,1))=cos(rad(yz)) v(in(rotx,1,2))=0-sin(rad(yz)) v(in(rotx,2,1))=sin(rad(yz)) v(in(rotx,2,2))=cos(rad(yz))
v(in(roty,0,0))=cos(rad(yz)) v(in(roty,0,2))=0-sin(rad(yz)) v(in(roty,2,0))=sin(rad(yz)) v(in(roty,2,2))=cos(rad(yz))
v(in(rotz,1,1))=cos(rad(yz)) v(in(rotz,1,0))=sin(rad(yz)) v(in(rotz,0,1))=0-sin(rad(yz)) v(in(rotz,0,0))=cos(rad(yz))
v(in(trans,3,0))=x v(in(trans,3,1))=y v(in(trans,3,2))=z
select case ax case xyz call mxmxm n , rotx , roty , rotz , p case xzy call mxmxm n , rotx , rotz , roty , p case yxz call mxmxm n , roty , rotx , rotz , p case yzx call mxmxm n , roty , rotz , rotx , p case zxy call mxmxm n , rotz , rotx , roty , p case zyx call mxmxm n , rotz , roty , rotx , p case else end select matrixno = n end sub sub skelet lim , x , y , z if lim < 0 or lim > 64 then exit sub sk(lim,0)=x sk(lim,1)=y sk(lim,2)=z end sub sub child n , x , y , z , lim , ax , p if lim < 0 or lim > 64 then exit sub call link n , x , y , z _ , sk(lim,1),sk(lim,0),sk(lim,2),ax,p end sub sub spot byref x , byref y , byref z hx=x*v(in(matrixno,0,0)) _ +y*v(in(matrixno,1,0)) _ +z*v(in(matrixno,2,0)) _ + v(in(matrixno,3,0)) hy=x*v(in(matrixno,0,1)) _ +y*v(in(matrixno,1,1)) _ +z*v(in(matrixno,2,1)) _ + v(in(matrixno,3,1)) hz=x*v(in(matrixno,0,2)) _ +y*v(in(matrixno,1,2)) _ +z*v(in(matrixno,2,2)) _ + v(in(matrixno,3,2)) x=hx:y=hy:z=hz end sub
|
|
|
Post by bluatigro on Jan 2, 2020 16:09:39 GMT
try at cube
error : my cube has a strange shape
time : 61397870 ms.
WindowWidth = DisplayWidth WindowHeight = DisplayHeight global winx , winy , pi winx = WindowWidth winy = WindowHeight pi = atn( 1 ) * 4 global uit.x,uit.y,uit.z global black,red,green,yellow global blue,magenta,cyan,white
black=rgb(0,0,0) red=rgb(255,0,0) green=rgb(0,255,0) yellow=rgb(255,255,0) blue=rgb(0,0,255) magenta=rgb(255,255,0) cyan=rgb(0,255,255) white=rgb(255,255,255) dim sph(100,8),tri(100,15),pnt(255,2) dim v(in(26,3,3)) , sk(64,3) global rotx,roty,rotz,trans,temp,temp2 rotx=21:roty=22:rotz=23:trans=24:temp=25:temp2=26 global xyz,xzy,yxz,yzx,zxy,zyx,matrixno xyz=0:xzy=1:yxz=2:yzx=3:zxy=4:zyx=5 global s.x,s.y,s.z,s.d,s.d2 global s.diffuse.r,s.diffuse.g,s.diffuse.b global s.reflect , sphtel global t.x1,t.y1,t.z1,t.x2,t.y2,t.z2,t.x3,t.y3,t.z3,t.nx,t.ny,t.nz global t.diffuse.r,t.diffuse.g,t.diffuse.b global t.reflect , tritel global l.r.x,l.r.y,l.r.z global l.g.x,l.g.y,l.g.z global l.b.x,l.b.y,l.b.z global p.x,p.y,p.z dim box(5) global infinity : infinity = 1e9 s.x=0:s.y=1:s.z=2:s.d = 3:s.d2 = 4 s.diffuse.r = 5:s.diffuse.g = 6:s.diffuse.b = 7 s.reflect = 8 t.x1=0:t.y1=1:t.z1=2 t.x2=3:t.y2=4:t.z2=5 t.x3=6:t.y3=7:t.z3=8 t.nx=9:t.ny=10:t.nz=11 t.difusse.r=12:t.diffuse.g=13:t.diffuse.b=14 t.reflect=15 p.x=0:p.y=1:p.z=2 nomainwin open "ray 2.0" for graphics as #m #m "trapclose [quit]" start = time$( "ms" ) call init3degine sphtel = 0 tritel = 0 call light -5,10,5 , 5,10,5 , 0,-10,5 call link 1 , 0,0,0 , 45,30,0 , yxz , 0 '' call sphere 50,0,0 , 50 , rgb(99,99,99) , .5 '' call sphere -50,0,0 , 50 , white , 0 '' call setpoint 0 , 0,40,0 '' call setpoint 1 , -40,-40,0 '' call setpoint 2 , 40,-40,0 '' call setpoint 3 , 0,0,-40 '' call tri 0 , 1 , 2 , white , 0 '' call tri 0 , 1 , 3 , white , 0 '' call tri 0 , 2 , 3 , white , 0 '' call tri 1 , 2 , 3 , white , 0 call setbox 0,0,0 , 70,70,70 call cube white , 0 for x = -100 to 100 for y = -100 to 100 scan call ray 0,0,-1000 , x,y,1000 , 7 call vuit r,g,b call pixel x,y , r,g,b next y next x notice "time : " ; time$( "ms" ) ; " ms." wait [quit] close #m end function atan2( x , y ) if abs( x ) < 1e-9 then if y < 0 then uit = 0 - pi / 2 else uit = pi / 2 end if else if x > 0 then uit = atn( y / x ) else uit = pi + atn( y / x ) end if end if atan2 = uit end function sub setpoint no , x,y,z call spot x,y,z pnt(no,p.x)=x pnt(no,p.y)=y pnt(no,p.z)=z end sub sub tri a , b , c , diffuse , reflect call triangle pnt(a,p.x),pnt(a,p.y),pnt(a,p.z) _ , pnt(b,p.x),pnt(b,p.y),pnt(b,p.z) _ , pnt(c,p.x),pnt(c,p.y),pnt(c,p.z) _ , diffuse , reflect end sub sub quad a , b , c , d , diffuse , reflect call tri a , b , c , diffuse , reflect call tri a , c , d , diffuse , reflect end sub sub light rx,ry,rz , gx,gy,gz , bx,by,bz l.r.x=rx l.r.y=ry l.r.z=rz l.g.x=gx l.g.y=gy l.g.z=gz l.b.x=bx l.b.y=by l.b.z=bz end sub function tri.hit(n , ox,oy,oz , dx,dy,dz ) call vmin tri(n,t.x2),tri(n,t.y2),tri(n,t.z2) _ , tri(n,t.x1),tri(n,t.y1),tri(n,t.z1) call vuit e1x,e1y,e1z call vmin tri(n,t.x3),tri(n,t.y3),tri(n,t.z3) _ , tri(n,t.x1),tri(n,t.y1),tri(n,t.z1) call vuit e2x,e2y,e2z call cross dx,dy,dz , e2x,e2y,e2z call vuit px,py,pz a = dot( e1x,e1y,e1z , px,py,pz ) if abs( a ) < 1e-9 then uit = infinity else f = 1 / a call vmin ox,oy,oz _ , tri(n,t.x1),tri(n,t.y1),tri(n,t.z1) call vuit sx,sy,sz u = f * dot( sx,sy,sz , px,py,pz ) if 0 > u or u > 1 then uit = infinity else call cross sx,sy,sz , e1x,e1y,e1z call vuit qx,qy,qz v = f * dot( dx,dy,dz , qx,qy,qz ) if v < 0 or v + u > 1 then uit = infinity else uit = f * dot( e2x,e2y,e2z , qx,qy,qz ) end if end if end if
tri.hit = uit end function sub triangle x1,y1,z1 , x2,y2,z2 , x3,y3,z3 , diffuse , reflect tri(tritel,t.x1)=x1 tri(tritel,t.y1)=y1 tri(tritel,t.z1)=z1 tri(tritel,t.x2)=x2 tri(tritel,t.y2)=y2 tri(tritel,t.z2)=z2 tri(tritel,t.x3)=x3 tri(tritel,t.y3)=y3 tri(tritel,t.z3)=z3 call cross x2-x1,y2-y1,z2-z1 , x3-x1,y3-y1,z3-z1 call vuit nx,ny,nz call vdiv nx,ny,nz , lenght( nx,ny,nz ) tri(tritel,t.nx)=nz tri(tritel,t.ny)=ny tri(tritel,t.nz)=nz r = ( int( diffuse ) and 255 ) / 256 g = ( int( diffuse / 256 ) and 255 ) / 256 b = ( int( diffuse / 256 ^ 2 ) and 255 ) / 256 tri( tritel , t.diffuse.r ) = r tri( tritel , t.diffuse.g ) = g tri( tritel , t.diffuse.b ) = b tri( tritel , t.reflect ) = reflect tritel = tritel + 1 end sub sub cross x1,y1,z1 , x2,y2,z2 uit.x = y1 * z2 - y2 * z1 uit.y = z1 * x2 - z2 * x1 uit.z = x1 * y2 - x2 * y1 end sub sub pixel x , y , r , g , b r = int( r * 256 ) and 255 g = int( g * 256 ) and 255 b = int( b * 256 ) and 255 #m "goto " ; winx / 2 + x ; " " ; winy / 2 - y #m "down" #m "color " ; r ; " " ; g ; " " ; b #m "set " ; winx / 2 + x ; " " ; winy / 2 - y #m "up" end sub sub ray ox,oy,oz , dx,dy,dz , dept low = infinity sphno = -1 for i = 0 to sphtel dist = sphere.hit(i,ox,oy,oz,dx,dy,dz) if dist < low then low = dist sphno = i end if next i tlow = infinity trino = -1 for i = 0 to tritel dist = tri.hit(i,ox,oy,oz,dx,dy,dz) if dist < tlow then tlow = dist trino = i end if next i if ( sphno = -1 and trino = -1 ) or dept < 0 then r = 0 g = 0 b = 0 else if low < tlow then r = sph(sphno,s.diffuse.r) g = sph(sphno,s.diffuse.g) b = sph(sphno,s.diffuse.b) ''hit point is ? call vmul dx,dy,dz , low call vuit dx,dy,dz call vadd ox,oy,oz , dx,dy,dz call vuit px,py,pz ''normal=p-sphere.centre call vmin px,py,pz , sph(sphno,s.x),sph(sphno,s.y),sph(sphno,s.z) call vuit nx,ny,nz ''normalize( normal ) call vdiv nx,ny,nz , lenght( nx,ny,nz ) call vuit nx,ny,nz ''getangle( normalize(normal) , sunlight ) ar = getangle( nx,ny,nz , l.r.x,l.r.y,l.r.z ) ag = getangle( nx,ny,nz , l.g.x,l.g.y,l.g.z ) ab = getangle( nx,ny,nz , l.b.x,l.b.y,l.b.z ) ''shadowing sphere r = r * cos(ar)/2+.5 g = g * cos(ag)/2+.5 b = b * cos(ab)/2+.5 if sph(sphno,s.reflect)>1e-5 then call mirror dx,dy,dz , nx,ny,nz call vuit dx,dy,dz call ray px,py,pz , dx,dy,dz , dept - 1 call vuit tr,tg,tb call vmin tr,tg,tb , r,g,b call vuit tr,tg,tb call vmul tr,tg,tb , sph(sphno,s.reflect) call vuit tr,tg,tb call vadd r,g,b , tr,tg,tb call vuit r,g,b end if else r = tri(trino,t.diffuse.r) g = tri(trino,t.difusse.g) b = tri(trino,t.diffuse.b) nx = tri(trino,t.nx) ny = tri(trino,t.ny) nz = tri(trino,t.nz) ''getangle( normalize(normal) , sunlight ) ar = getangle( nx,ny,nz , l.r.x,l.r.y,l.r.z ) ag = getangle( nx,ny,nz , l.g.x,l.g.y,l.g.z ) ab = getangle( nx,ny,nz , l.b.x,l.b.y,l.b.z ) ''shadowing triangle r = r * cos(ar)/2+.5 g = g * cos(ag)/2+.5 b = b * cos(ab)/2+.5 if tri(trino,reflect)>1e-5 then ''hit point is ? call vmul dx,dy,dz , low call vuit dx,dy,dz call vadd ox,oy,oz , dx,dy,dz call vuit px,py,pz call mirror dx,dy,dz , nx,ny,nz call vuit dx,dy,dz call ray px,py,pz , dx,dy,dz , dept - 1 call vuit tr,tg,tb call vmin tr,tg,tb , r,g,b call vuit tr,tg,tb call vmul tr,tg,tb , tri(trino,t.reflect) call vuit tr,tg,tb call vadd r,g,b , tr,tg,tb call vuit r,g,b end if end if end if ''put output in uit vector uit.x = r uit.y = g uit.z = b end sub sub sphere x,y,z , d , diffuse , reflect call spot x,y,z sph( sphtel , s.x ) = x sph( sphtel , s.y ) = y sph( sphtel , s.z ) = z sph( sphtel , s.d ) = d sph( sphtel , s.d2 ) = d * d r = ( int( diffuse ) and 255 ) / 256 g = ( int( diffuse / 256 ) and 255 ) / 256 b = ( int( diffuse / 256 ^ 2 ) and 255 ) / 256 sph( sphtel , s.diffuse.r ) = r sph( sphtel , s.diffuse.g ) = g sph( sphtel , s.diffuse.b ) = b sph( sphtel , s.reflect ) = reflect sphtel = sphtel + 1 end sub function rgb( r , g , b ) rgb = r + g * 256 + b * 256 ^ 2 end function function sphere.hit( no , ox,oy,oz, dx,dy,dz ) call vmin ox,oy,oz , sph(no,s.x),sph(no,s.y),sph(no,s.z) call vuit tx,ty,tz a = dot( dx,dy,dz , dx,dy,dz ) b = 2 * dot( tx,ty,tz , dx,dy,dz ) c = dot( tx,ty,tz , tx,ty,tz ) - sph(no,s.d2) disc = b ^ 2 - 4 * a * c uit = infinity if disc >= 0 then e = sqr( disc ) demon = 2 * a t = ( 0 - b - e ) / demon if t > 1e-9 then uit = t end if t = ( 0 - b + e ) / demon if t > 1e-9 then uit = t end if end if sphere.hit = uit end function sub vuit byref x,byref y, byref z x = uit.x y = uit.y z = uit.z end sub sub vadd x1,y1,z1 , x2,y2,z2 ''uit = v1 + v2 uit.x = x1 + x2 uit.y = y1 + y2 uit.z = z1 + z2 end sub sub vmin x1,y1,z1 , x2,y2,z2 ''uit = v1 - v2 uit.x = x1 - x2 uit.y = y1 - y2 uit.z = z1 - z2 end sub sub vmul x1,y1,z1 , d ''uit = v1 * d uit.x = x1 * d uit.y = y1 * d uit.z = z1 * d end sub sub vdiv x1,y1,z1 , d ''uit = v1 / d if d = 0 then d = 0.0001 uit.x = x1 / d uit.y = y1 / d uit.z = z1 / d end sub sub mirror x,y,z, nx,ny,nz xz = atan2( nx , nz ) yz = atan2( ny , nz ) call rotate nx , nz , xz call rotate x , z , xz call rotate y , z , yz z = 0 - z call rotate y , z , 0 - yz call rotate x , z , 0 - xz uit.x = x uit.y = y uit.z = z end sub sub rotate byref k, byref l,radians s = sin( radians ) c = cos( radians ) hk = k * c - l * s hl = k * s + l * c k = hk l = hl end sub function getangle( x1,y1,z1 , x2,y2,z2 ) l1 = lenght( x1,y1,z1 ) + 0.0001 l2 = lenght( x2,y2,z2 ) + 0.0001 d = dot( x1,y1,z1 , x2,y2,z2 ) getangle = acs( d / ( l1 * l2 ) ) end function function lenght( x,y,z ) ''uit = | v | lenght = sqr( dot( x,y,z , x,y,z ) ) end function function dot( a,b,c , d,e,f ) dot = a*d + b*e + c*f end function [3dengine] function rad( deg ) rad = deg * pi / 180 end function function in(n,x,y) in = n * 16 + x * 4 + y end function sub init3degine for i = 0 to 3 for j = 0 to 3 v(in(0,i,j))=0 next j v(in(0,i,i))=1 next i end sub sub copy uit , n for i = 0 to 3 for j = 0 to 3 v(in(uit,i,j))=v(in(n,i,j)) next j next i end sub sub mxm uit , a , b for i = 0 to 3 for j = 0 to 3 v(in(uit,i,j))=0 for k = 0 to 3 v(in(uit,i,j))=v(in(uit,i,j)) _ + v(in(a,i,k)) * v(in(b,k,j)) next k next j next i end sub sub mxmxm uit , a , b , c , p call mxm temp , a , b call mxm temp2 , temp , c call mxm temp , temp2 , trans call mxm temp2 , temp , p call copy uit , temp2 end sub sub link n , x,y,z , xz,xy,yz , ax , p if n < 1 or n > 20 then exit sub if p < 0 or p > 20 then exit sub if p = n then exit sub
call copy rotx , 0 call copy roty , 0 call copy rotz , 0 call copy trans , 0
v(in(rotx,1,1))=cos(rad(yz)) v(in(rotx,1,2))=0-sin(rad(yz)) v(in(rotx,2,1))=sin(rad(yz)) v(in(rotx,2,2))=cos(rad(yz))
v(in(roty,0,0))=cos(rad(yz)) v(in(roty,0,2))=0-sin(rad(yz)) v(in(roty,2,0))=sin(rad(yz)) v(in(roty,2,2))=cos(rad(yz))
v(in(rotz,1,1))=cos(rad(yz)) v(in(rotz,1,0))=sin(rad(yz)) v(in(rotz,0,1))=0-sin(rad(yz)) v(in(rotz,0,0))=cos(rad(yz))
v(in(trans,3,0))=x v(in(trans,3,1))=y v(in(trans,3,2))=z
select case ax case xyz call mxmxm n , rotx , roty , rotz , p case xzy call mxmxm n , rotx , rotz , roty , p case yxz call mxmxm n , roty , rotx , rotz , p case yzx call mxmxm n , roty , rotz , rotx , p case zxy call mxmxm n , rotz , rotx , roty , p case zyx call mxmxm n , rotz , roty , rotx , p case else end select matrixno = n end sub sub skelet lim , x , y , z if lim < 0 or lim > 64 then exit sub sk(lim,0)=x sk(lim,1)=y sk(lim,2)=z end sub sub child n , x , y , z , lim , ax , p if lim < 0 or lim > 64 then exit sub call link n , x , y , z _ , sk(lim,1),sk(lim,0),sk(lim,2),ax,p end sub sub spot byref x , byref y , byref z hx=x*v(in(matrixno,0,0)) _ +y*v(in(matrixno,1,0)) _ +z*v(in(matrixno,2,0)) _ + v(in(matrixno,3,0)) hy=x*v(in(matrixno,0,1)) _ +y*v(in(matrixno,1,1)) _ +z*v(in(matrixno,2,1)) _ + v(in(matrixno,3,1)) hz=x*v(in(matrixno,0,2)) _ +y*v(in(matrixno,1,2)) _ +z*v(in(matrixno,2,2)) _ + v(in(matrixno,3,2)) x=hx:y=hy:z=hz end sub [triangle.shapes] sub setbox x,y,z , dx,dy,dz box(0)=x box(1)=y box(2)=z box(3)=dx box(4)=dy box(5)=dz end sub sub cube diffuse , reflect '' example mesh : cube '' fill swarm whit points call setpoint 0,box(0)+box(3),box(1)+box(4),box(2)+box(5) call setpoint 1,box(0)+box(3),box(1)+box(4),box(2)-box(5) call setpoint 2,box(0)+box(3),box(1)-box(4),box(2)+box(5) call setpoint 3,box(0)+box(3),box(1)-box(4),box(2)-box(5) call setpoint 4,box(0)-box(3),box(1)+box(4),box(2)+box(5) call setpoint 5,box(0)-box(3),box(1)+box(4),box(2)-box(5) call setpoint 6,box(0)-box(3),box(1)-box(4),box(2)+box(5) call setpoint 7,box(0)-box(3),box(1)-box(4),box(2)-box(5) '' use points out of swarm for quad's | tri's call quad 0,1,3,2 , diffuse , reflect call quad 7,6,4,5 , diffuse , reflect call quad 0,1,5,4 , diffuse , reflect call quad 7,6,2,3 , diffuse , reflect call quad 0,2,6,4 , diffuse , reflect call quad 7,5,1,3 , diffuse , reflect end sub
|
|