x4nd Newbie
Joined: 05/07/2020 Location: United KingdomPosts: 11 |
Posted: 07:17pm 25 Aug 2020 |
Copy link to clipboard |
Print this post |
|
Hi,
Last one of these before I start working on Battlezone. I modified the other 3d football demo (the one with coloured polygons) to use the inbuilt MATH functions. I also took the liberty of adding an extra effect and some more optimisation.
Thanks Peter and Geoff for all of your excellent work - this is such a fun computer!
football.bas:
option explicit option default none
'use this to set the output to 640x480x256 colours mode 3,16
'use this if we want to double-buffer the output (slower?) page write 1
'cls
const edgelength=100 'set the length of the verticies of the ticosahedron const zlocation=3000 'how far is the center of the ticosahedron away from us const viewplane=1000 'how far is the viewplane away from us
'these arrays store our object vertices (60 vertices) 'ticos is an array of simple vertices 'nticos is an array of 60 quaternions - 5 values containing: w,x,y,z,magnitude dim float ticos(59,2), nticos(59,4), polypos(32,4) 'this holds the sorted z positions of the polygons dim integer index(31) ' this holds our 2d vertices dim integer screen(59,1)
'temporary variables dim integer i, j, k, k2, found dim float x,y,z,d,x1,y1 dim float v(4), vout(4)
'use this if we want to display the FPS counter dim string jout
' ' data for location of verticies for truncated icosahedron of edge length 2 ' dim float phi=(1+sqr(5))/2 data 0,1,3*phi data 0,1,-3*phi data 0,-1,3*phi data 0,-1,-3*phi data 1,3*phi,0 data 1,-3*phi,0 data -1,3*phi,0 data -1,-3*phi,0 data 3*phi,0,1 data 3*phi,0,-1 data -3*phi,0,1 data -3*phi,0,-1 data 2,(1+2*phi),phi data 2,(1+2*phi),-phi data 2,-(1+2*phi),phi data 2,-(1+2*phi),-phi data -2,(1+2*phi),phi data -2,(1+2*phi),-phi data -2,-(1+2*phi),phi data -2,-(1+2*phi),-phi data (1+2*phi),phi,2 data (1+2*phi),phi,-2 data (1+2*phi),-phi,2 data (1+2*phi),-phi,-2 data -(1+2*phi),phi,2 data -(1+2*phi),phi,-2 data -(1+2*phi),-phi,2 data -(1+2*phi),-phi,-2 data phi,2,(1+2*phi) data phi,2,-(1+2*phi) data phi,-2,(1+2*phi) data phi,-2,-(1+2*phi) data -phi,2,(1+2*phi) data -phi,2,-(1+2*phi) data -phi,-2,(1+2*phi) data -phi,-2,-(1+2*phi) data 1,(2+phi),2*phi data 1,(2+phi),-2*phi data 1,-(2+phi),2*phi data 1,-(2+phi),-2*phi data -1,(2+phi),2*phi data -1,(2+phi),-2*phi data -1,-(2+phi),2*phi data -1,-(2+phi),-2*phi data (2+phi),2*phi,1 data (2+phi),2*phi,-1 data (2+phi),-2*phi,1 data (2+phi),-2*phi,-1 data -(2+phi),2*phi,1 data -(2+phi),2*phi,-1 data -(2+phi),-2*phi,1 data -(2+phi),-2*phi,-1 data 2*phi,1,(2+phi) data 2*phi,1,-(2+phi) data 2*phi,-1,(2+phi) data 2*phi,-1,-(2+phi) data -2*phi,1,(2+phi) data -2*phi,1,-(2+phi) data -2*phi,-1,(2+phi) data -2*phi,-1,-(2+phi) ' 12 faces with 5 sides data 0,28,36,40,32 data 1,29,37,41,33 data 2,30,38,42,34 data 3,31,39,43,35 data 4,12,44,45,13 data 5,14,46,47,15 data 6,16,48,49,17 data 7,18,50,51,19 data 8,20,52,54,22 data 9,21,53,55,23 data 10,24,56,58,26 data 11,27,59,57,25 ' 20 faces with 6 sides data 0,2,34,58,56,32 data 0,2,30,54,52,28 data 1,3,31,55,53,29 data 1,3,35,59,57,33 data 4,6,17,41,37,13 data 4,6,16,40,36,12 data 5,7,19,43,39,15 data 5,7,18,42,38,14 data 8,9,23,47,46,22 data 8,9,21,45,44,20 data 10,11,27,51,50,26 data 10,11,25,49,48,24 data 12,44,20,52,28,36 data 13,45,21,53,29,37 data 14,46,22,54,30,38 data 15,47,23,55,31,39 data 16,48,24,56,32,40 data 17,49,25,57,33,41 data 18,50,26,58,34,42 data 19,51,27,59,35,43
'polygon information dim integer nv(31)=(5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6) dim integer np(31)=(0,1,2,3,4,5,6,7,8,9,10,11,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19) dim integer f5(4,11), f6(5,19), nd(23), xarr(136), yarr(136), ncol(31) dim integer m, l ' ' read in the x,y,z coordinates of the 60 verticies and scale by edgelength ' for i=0 to 59 for j=0 to 2 read ticos(i,j) ticos(i,j)=ticos(i,j)*edgelength/2 next j next i
' read in the polygon data (5 sided and 6-sided) for j=0 to 11 for i=0 to 4 read f5(i,j) next i next j for j=0 to 19 for i=0 to 5 read f6(i,j) next i next j
' 'convert x,y,z coordinates to normalised form and save as quaternions (w,x,y,z,magnitude) ' for i=0 to 59 create_vector(ticos(i,0),ticos(i,1),ticos(i,2),v()) nticos(i,0)=v(0): nticos(i,1)=v(1): nticos(i,2)=v(2): nticos(i,3)=v(3): nticos(i,4)=v(4) next i
'calculate the center of each polygon (average x,y,x,mag) 'average the positions for the 5 sided faces for k=0 to 11 polypos(k,0)=0 polypos(k,1)=0 polypos(k,2)=0 polypos(k,3)=0 for i=0 to 4 polypos(k,0)=polypos(k,0)+nticos(f5(i,k),0) polypos(k,1)=polypos(k,1)+nticos(f5(i,k),1) polypos(k,2)=polypos(k,2)+nticos(f5(i,k),2) polypos(k,3)=polypos(k,3)+nticos(f5(i,k),3) next i polypos(k,0)=polypos(k,0)/5 polypos(k,1)=polypos(k,1)/5 polypos(k,2)=polypos(k,2)/5 polypos(k,3)=polypos(k,3)/5 next k
'average the positions for the 6 sided faces for k=12 to 31 polypos(k,0)=0 polypos(k,1)=0 polypos(k,2)=0 polypos(k,3)=0 for i=0 to 5 polypos(k,0)=polypos(k,0)+nticos(f6(i,k-12),0) polypos(k,1)=polypos(k,1)+nticos(f6(i,k-12),1) polypos(k,2)=polypos(k,2)+nticos(f6(i,k-12),2) polypos(k,3)=polypos(k,3)+nticos(f6(i,k-12),3) next i polypos(k,0)=polypos(k,0)/6 polypos(k,1)=polypos(k,1)/6 polypos(k,2)=polypos(k,2)/6 polypos(k,3)=polypos(k,3)/6 next k
' 'create a quarternion to rotate 2 degrees about a chosen axis 'play with the x,y,z vector which is the sxis of rotation ' dim float rot(4),rnow(4)
'use this if we want to count the FPS 'dim integer frames=0 'SETTICK 1000,framecounter
'find the center of the screen dim integer hcenter = MM.HRES/2 dim integer vcenter = MM.VRES/2 'temp variable to reduce #calculations dim float zpos(31) dim float ztmp,rval=0.02,xval=0.5,yval=0.5,zval=0.5 dim integer ind,cnt,pol,brite ' ' MAIN LOOP ' do 'update the rotation vector MATH Q_CREATE rval,xval,yval,zval,rot() rval=rval+0.07 xval=cos(rval/1041) yval=tan(rval/1232) zval=cos(rval/61)
'rotate the object nticos() using rotation vector rot() (60 vertices) for i=0 to 59 v(1)=nticos(i,1): v(2)=nticos(i,2): v(3)=nticos(i,3): v(4)=nticos(i,4) MATH Q_ROTATE rot(),v(),vout() 'transform this 3d vertex into a 2d location on screen and store it ztmp=viewplane/(vout(3)+zlocation)*vout(4) screen(i,0)=vout(1)*ztmp+hcenter screen(i,1)=vout(2)*ztmp+vcenter next i 'rotate the polypos() object using the same rotation vector rot() (32 polygons) for i=0 to 31 v(1)=polypos(i,1): v(2)=polypos(i,2): v(3)=polypos(i,3): v(4)=polypos(i,4) MATH Q_ROTATE rot(),v(),vout() 'store the z positions of the polygons zpos(i)=vout(3) next i 'sort the polygon positions sort zpos(),index()
'draw the polygons on screen starting with the farthest away. Ignore farthest 9 polygons j=0 for l=8 to 31 k=index(l) m=np(k) cnt=nv(k) pol=l-8 nd(pol)=cnt 'polygon brightness depends on distance from the viewer brite=l*8 if 32=l then brite=255 end if if cnt=5 then ncol(pol)=rgb(brite,0,0) for i=0 to 4 ind=f5(i,m) xarr(j)=screen(ind,0) yarr(j)=screen(ind,1) j=j+1 next i else ncol(pol)=rgb(brite,brite,brite) for i=0 to 5 ind=f6(i,m) xarr(j)=screen(ind,0) yarr(j)=screen(ind,1) j=j+1 next i endif next l
' clear screen and draw the polygon cls polygon nd(),xarr(),yarr(),rgb(black),ncol() 'use this if we want to display the FPS 'text 0,0,jout,L 'frames=frames+1
'copy the frame from page 1 to 0 (0=the view) page copy 1 to 0
'have we tapped 'ESC'? IF INKEY$ = CHR$(27) THEN END loop
' ' SUBROUTINES ' 'use if we want an on-screen FPS counter sub framecounter() jout="FPS="+STR$(frames):frames=0 end sub
'function to create a new vecotr sub create_vector(x as float,y as float ,z as float,v() as float) v(4)=sqr(x*x + y*y + z*z)'magnitude (4th field of quaternion) v(0)=0'w v(1)=x/v(4)'x v(2)=y/v(4)'y v(3)=z/v(4)'z end sub
Edited 2020-08-26 18:55 by x4nd If only there were more hours in the day.. |