'
'        Helicopter Coded by Shockwave (C) 2002.
'
'This object was suggested by the forum users at the
'message boards on www.yabasic.co.uk when I was after a
'few ideas for new objects.
'It consists of 33 points and 28 faces. 
'some faces needed to be defined twice like the rotors
'because they are displayed if positive or negative area.
'
'It's quite an interesting one as it shows a limitation
'of the routine when dealing with long polygons. As some 
'of the faces are of wildly differing sizes it causes
'sort problems. If you look carefully you'll notice that
'the draw order for the faces is sometimes screwed up.
'
'This is a real headache. It's not happening because the
'code is bugged, the object is just unsuitable for the
'routine. To combat this I could either;
'
'Define the object out of many more points and faces.
'Or;
'Z buffer the whole object.
'
'Both solutions are impractical because they'd run too
'slowly. The problem is only slight but it is noticeable.
'Unfortunately Yabasic is just too slow to fix them.
'
'This is the second demo in Yabasic featuring an animated
'object, Fryer's Newtons cradle was the first.
'---------------------------------------------------------
gosub initialise
'^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
repeat
    setdrawbuf dw
    dw=1-dw
    setdispbuf dw
setrgb 1,0,20,20
setrgb 2,20,0,20
setrgb 3,0,0,20
gtriangle 0,0 to 640,512 to 0,512
gtriangle 0,0 to 640,512 to 640,0
    gosub rotors
    gosub rotate
    gosub construct
setrgb 1,255,255,255
text 50,50,"POLYS DRAWN:"+str$(visible)
until (and(peek("port1"),16384)<>0)
exit

label rotors
rv=rv+35
for a=29 to 32
 z(a)=-5.5
next a
 x(29)=10*sin(rv*pi/180)
 y(29)=10*cos(rv*pi/180)
 x(30)=10*sin((rv+5)*pi/180)
 y(30)=10*cos((rv+5)*pi/180)

 x(31)=10*sin((rv+180)*pi/180)
 y(31)=10*cos((rv+180)*pi/180)
 x(32)=10*sin((rv+185)*pi/180)
 y(32)=10*cos((rv+185)*pi/180)
 x(33)=0
 y(33)=0
 z(33)=-5.5
return

'---------------------------------------------------------
'                     Draw The Object;
'---------------------------------------------------------
label construct
gosub draworder
for b=1 to visible
a=sort(b)
gosub draw
next b
return

'---------------------------------------------------------
'      Find Visible Faces, Sort them into order;
'---------------------------------------------------------

label draworder
visible=0
for a=1 to faces
  vx1= tx(f1(a))-tx(f2(a))
  vy1= ty(f1(a))-ty(f2(a))
  vx2= tx(f3(a))-tx(f2(a))
  vy2= ty(f3(a))-ty(f2(a))
  n(a)=  vx1*vy2-vx2*vy1
 if n(a)<0 then
 visible=visible+1
 sort(visible)=a
 n(a)=-(n(a)/150)
 fi
next a

for fk=1 to visible
for a=1 to visible-1
'get low z
 ref=sort(a)
 low=tz(f1(ref))
 if low<tz(f2(ref)) low=tz(f2(ref))
 if low<tz(f3(ref)) low=tz(f3(ref))
 if low<tz(f4(ref)) low=tz(f4(ref))
'get low z
 ref=sort(a+1)
 low2=tz(f1(ref))
 if low2<tz(f2(ref)) low2=tz(f2(ref))
 if low2<tz(f3(ref)) low2=tz(f3(ref))
 if low2<tz(f4(ref)) low2=tz(f4(ref))
 
if low2>low then
 temp=sort(a+1)
 sort(a+1)=sort(a)
 sort(a)=temp
fi

next a
next fk

return

'---------------------------------------------------------
'              Draw A Face Of The Object;
'---------------------------------------------------------

label draw
 setrgb 1,r(a)+n(a),g(a)+n(a),b(a)+n(a)
 fill triangle tx(f1(a)),ty(f1(a)) to tx(f2(a)),ty(f2(a)) to tx(f3(a)),ty(f3(a))
 fill triangle tx(f1(a)),ty(f1(a)) to tx(f4(a)),ty(f4(a)) to tx(f3(a)),ty(f3(a))
 if cls(a)=1 then
   setrgb 1,0,0,0
   line tx(f1(a)),ty(f1(a)) to tx(f2(a)),ty(f2(a))
   line tx(f2(a)),ty(f2(a)) to tx(f3(a)),ty(f3(a))
   line tx(f3(a)),ty(f3(a)) to tx(f4(a)),ty(f4(a))
   line tx(f4(a)),ty(f4(a)) to tx(f1(a)),ty(f1(a))
 fi
return

label rotate
'---------------------------------------------------------
'       Rotate And Scale Each Point! Store Result;
'---------------------------------------------------------
 for a=1 to points
  x1=x(a)
  y1=y(a)
  z1=z(a)+5
'---------------------------------------------------------
'                      X,Y,Z rotations;
'---------------------------------------------------------
  xx=x1
  yy=y1*cs(xr)+z1*sn(xr)
  zz=z1*cs(xr)-y1*sn(xr)
  y1=yy
  x1=xx*cs(yr)-zz*sn(yr)
  z1=xx*sn(yr)+zz*cs(yr)
  zz=z1
  xx=x1*cs(zr)-y1*sn(zr)
  yy=x1*sn(zr)+y1*cs(zr)
'---------------------------------------------------------
'                 Perspective Transformation;
'---------------------------------------------------------
  dv=(zz/40)+1
  xx=size*(xx/dv)+320
  yy=size*(yy/dv)+256
  tx(a)=xx
  ty(a)=yy
  tz(a)=zz
 next a
'---------------------------------------------------------
'                 Rotation adds and resets;
'---------------------------------------------------------
xr=xr+5
yr=yr+3
zr=zr+7
if xr>720 xr=xr-720
if yr>720 yr=yr-720
if zr>720 zr=zr-720
return

'^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
' This Sub-Routine Initialises The Program.
'^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
label initialise
'---------------------------------------------------------
'                     Open Gfx Screen!
'---------------------------------------------------------

 open window 640,512

'---------------------------------------------------------
'            Define the necessary variables;
'---------------------------------------------------------
'       Change the three below to suit your object;
'_________________________________________________________
size=20: rem                       how big do you want it?
points=33: Rem          The amount of points in the object
faces=28 : Rem           The Amount of faces in the object
'_________________________________________________________
'                  Leave these all alone;
dw=1 : Rem                       Double buffering Variable
dim x(points): Rem          Original X co-ordinate store
dim y(points): Rem          Original Y co-ordinate store
dim z(points): Rem          Original Z co-ordinate store
dim tx(points): Rem     Transformed  X co-ordinate store
dim ty(points): Rem      Transformed Y co-ordinate store
dim tz(points): Rem      Transformed Z co-ordinate store
dim f1(faces):rem                   Connections definition
dim f2(faces):rem                   Connections definition
dim f3(faces):rem                   Connections definition
dim f4(faces):rem                   Connections definition
dim r(faces):rem                             Red Component
dim g(faces):rem                           Green Component
dim b(faces):rem                            Blue Component
dim cls(faces):rem                        Cell Shade Face?
dim sort(faces):rem                          Drawing order
dim n(faces):rem                           Surface normals
'---------------------------------------------------------
'   Define Sine Tables for faster matrix calculations;
'---------------------------------------------------------
 dim cs(720)
 dim sn(720)
 for ang=0 to 720
  cs(ang)=cos(ang*(pi/360))
  sn(ang)=sin(ang*(pi/360))
 next ang
'---------------------------------------------------------
'               Read in the object's points;
'---------------------------------------------------------
for a=1 to points-5
 read x(a),y(a),z(a)
next a
'---------------------------------------------------------
'         Read In Connections and face parameters;
'---------------------------------------------------------
for a=1 to faces
read f1(a)
read f2(a)
read f3(a)
read f4(a)
read r(a),g(a),b(a),cls(a)
next a
'^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
'   The Object Description As Data!
'^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

'Points definition;
'~~~~~~~~~~~~~~~~~~
'Below are the points of the object defined as x,y,z;
'This object was created vith vector object editor v1.0
'by Shockwave. Object designed by Shockwave.

data 5,3,-4,-3,3,-4,-3,-3,-4,5,-3,-4
data 5,-3,2,5,3,2,-3,3,2,-3,-3,2
data 9,-1,0,9,1,0,-5,1,-1,-5,-1,-1
data -5,-1,1,-5,1,1
data -12,0,-1,-10,0,-1,-10,0,1,-12,0,1
data -12,0,-5,-11,0,-5
data 2,-2,2,0,-2,2,-4,-3,4,5,-3,4
data 2,2,2,0,2,2,-4,3,4,5,3,4

'Connection definition;
'~~~~~~~~~~~~~~~~~~~~~~
'Below are the faces of the object defined as vertice
'numbers, specified in clockwise order. These are followed
'by r,g,b values for the face and finally cell shaded
'parameter (0)=off (1)=on.
'
'eg:
'join points 1 to 2 to 3 to 4 to 1
'golour 10red 20 blue 30 green cell shade on would be;
'
'data 1,2,3,4,10,20,30,1

data 1,2,3,4,1,1,1,1
data 8,7,6,5,1,1,1,1
data 8,5,4,3,1,1,1,1
data 7,2,1,6,1,1,1,1
data 4,5,9,9,1,1,1,1
data 1,4,9,10,1,1,51,1
data 6,10,9,5,1,1,1,1
data 6,1,10,10,1,1,1,1
data 7,8,13,14,1,1,1,1
data 13,8,3,12,1,1,1,1
data 11,12,3,2,1,1,1,1
data 14,11,2,7,1,1,1,1
data 13,12,16,17,1,1,1,1
data 17,14,13,13,1,1,1,1
data 11,16,12,12,1,1,1,1
data 14,17,16,11,1,1,1,1
data 18,17,16,15,1,1,1,1
data 15,16,17,18,1,1,1,1
data 15,16,20,19,1,1,1,1
data 19,20,16,15,1,1,1,1

data 23,24,21,22,1,1,1,1
data 22,21,24,23,1,1,1,1

data 27,28,25,26,1,1,1,1
data 26,25,28,27,1,1,1,1

data 29,30,33,33,1,1,1,1

data 30,29,33,33,1,1,1,1
data 32,31,33,33,1,1,1,1
data 31,32,33,33,1,1,1,1

return












