Home
JAQForum Ver 20.06
Log In or Join  
Active Topics
Local Time 16:37 20 May 2024 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : Peter's football demo using MATH calls

Author Message
x4nd
Newbie

Joined: 05/07/2020
Location: United Kingdom
Posts: 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..
 
Print this page


To reply to this topic, you need to log in.

© JAQ Software 2024