'mode > 0=play final only  1=show as calculated
mode=0

'length of animation (50 frames=1 sec.)
max_frames=360

'frames fade in/out (0 frames=no fade)
fade_in=0
fade_out=0

'focal length (increase>zoom decrease>wide_angle)
fl=700

'set storage space for animation
'if yabasic out of memory decrease this value
'but will shorten max animation length
max_poly=90000

'run program
goto anim

'object and camera control routine
label control
'  rot_cam(0,0,2)
  if loop=1 then
'    for i=13 to 27
'      obj_on(i,0)
'    next i
    rot_obj(2,0,0,45)
    for i=14 to 15
      scale_to(i,.6,3.2,.2,0)
    next i
    for i=18 to 21
      scale_to(i,.2,.2,.3,0)
    next i
    scale_to(22,1,9,1,0)
    scale_to(23,.3,.3,1.5,0)
    scale_to(24,.1,.1,1.5,0)
    scale_to(25,.1,.1,1.5,0)
    scale_to(26,3,1,3,0)
    scale_to(27,3,1,3,0)
    rot_obj(27,180,0,0)
    rot_obj(4,0,0,-90)
    rot_obj(5,0,0,180)
    rot_obj(6,0,0,90)
    rot_obj(9,0,0,-90)
    rot_obj(10,0,0,180)
    rot_obj(11,0,0,90)
  fi
  rot_obj(23,0,0,4)  
  rot_obj(22,0,-1,0)
  rot_obj(2,0,0,-3)
  rot_obj(1,0,0,3)
return

label pallete_data
'number of colors defined (1-31)
data 7
'---RGB values for colors,,,shading mode(0-3)
'shade +4(no fade in) +8(no fade out) +12(no fade in/out)
data 225,215,100,2
data 255,255,255,2
data 70,40,10,1
data 90,80,30,2
data 60,70,60,1
data 40,45,20,3
data 30,30,10,1

label model_data
'---number of models
data 6

'---model 1
'---number of points
data 12
'---3d coords of points
data -50,-50,-50
data -50,-50,50
data 50,-50,50
data 50,-50,-50
data -50,50,-50
data -50,50,50
data 50,50,50
data 50,50,-50
data 0,0,-300
data 0,0,-125
data 0,4,-125
data 0,-4,-125
'---number of faces
data 10
'---3 points per face(clockwise),color(+32 for half_brite)
data 1,2,6,1,1,4
data 1,6,5,1,4,4
data 2,3,7,1,1,1
data 2,7,6,1,1,1
data 3,4,8,1,1,4
data 3,8,7,1,4,4
data 4,1,5,1,1,1
data 4,5,8,1,1,1
data 1,3,2,1,1,1
data 1,4,3,1,1,1

'---model 2
'---number of points
data 5
'---3d coords of points
data 0,0,0
data -100,0,0
data 0,100,0
data 100,0,0
data 0,-100,0
'---number of faces
data 0
'---3 points per face(clockwise),color(+32 for half_brite)

'---model 3
'---number of points
data 4
'---3d coords of points
data 0,135,0
data 0,-135,0
data 0,0,90
data 0,0,-90
'---number of faces
data 0
'---3 points per face(clockwise),color(+32 for half_brite)

'---model 4
'---number of points
data 4
'---3d coords of points
data 0,0,65
data 0,0,-65
data 0,0,110
data 0,0,-110
'---number of faces
data 0
'---3 points per face(clockwise),color(+32 for half_brite)

'---model 5
'---number of points
data 8
'---3d coords of points
data -50,-50,-50
data -50,-50,50
data 50,-50,50
data 50,-50,-50
data -50,50,-50
data -50,50,50
data 50,50,50
data 50,50,-50
'---number of faces
data 4
'---3 points per face(clockwise),color(+32 for half_brite)
data 2,3,7,1,1,1
data 2,7,6,1,1,1
data 4,1,5,1,1,1
data 4,5,8,1,1,1

'---model 6
'---number of points
data 8
'---3d coords of points
data -50,-50,-50
data -50,-50,50
data 50,-50,50
data 50,-50,-50
data -50,50,-50
data -50,50,50
data 50,50,50
data 50,50,-50
'---number of faces
data 8
'---3 points per face(clockwise),color(+32 for half_brite)
data 1,2,6,1,1,1
data 1,6,5,1,1,1
data 3,4,8,1,1,1
data 3,8,7,1,1,1
data 1,3,2,1,1,1
data 1,4,3,1,1,1
data 5,6,7,1,1,1
data 5,7,8,1,1,1

label object_data
'---number of objects
data 27
'---model number of object,3D coords,,,color offset
data 2,0,0,0,0
data 2,0,0,0,0
data 5,0,0,0,0
data 1,0,0,0,0
data 1,0,0,0,0
data 1,0,0,0,0
data 1,0,0,0,0
data 5,0,0,0,1
data 1,0,0,0,1
data 1,0,0,0,1
data 1,0,0,0,1
data 1,0,0,0,1
data 3,0,0,0,0
data 1,0,0,0,0
data 1,0,0,0,0
data 4,0,0,0,0
data 4,0,0,0,0
data 6,0,0,0,0
data 6,0,0,0,0
data 6,0,0,0,1
data 6,0,0,0,1
data 1,0,0,1500,2
data 6,0,0,0,0
data 6,0,0,0,0
data 6,0,0,0,0
data 1,0,500,1500,3
data 1,0,-500,1500,3

label link_data 
'number of links
data 24

'object to be linked,
'      object to be linked to,
'            point of object to be linked to,
'                 rotation(+1)/scaling(+2) linked
data 1,13,1,1
data 2,13,2,1
data 3,1,1,1
data 4,1,2,1
data 5,1,3,1
data 6,1,4,1
data 7,1,5,1
data 8,2,1,1
data 9,2,2,1
data 10,2,3,1
data 11,2,4,1
data 12,2,5,1
data 14,13,3,1
data 15,13,4,1

data 16,1,1,1
data 17,2,1,1
data 18,16,1,1
data 19,16,2,1
data 20,17,1,1
data 21,17,2,1
data 13,22,9,1
data 23,22,10,1
data 24,22,11,1
data 25,22,12,1

'*********************************************************
'*** WARNING - Do not alter any code beyond this point ***
'*********************************************************
'                      Yanimate V1.0
'              YaBasic 3D graphics Animation
'                   By R.A.Fryer  2002
'
'
'e-mail R.Fryer@BTInternet.com
'
'Thanks to Jomorrow and Asiv at www.yabasic.co.uk
'for some great ideas and advice.
'And thanks to Nick Simpson for the X-port

label anim
  ss=0
  ref=.55:bright=95
  dim sn(5760),cs(5760)
  for i=0 to 5760
    sn(i)=sin(i/2880*pi)
    cs(i)=cos(i/2880*pi)
  next i
  restore pallete_data
  read mcols
  if mcols>31 or mcols<1 then
    print" Pallete data error - number of colors (1-31)"
    end
  fi
  mxcols=mcols*64+63
  dim r(mxcols),g(mxcols),b(mxcols)
  dim light(mcols)
  for i=1 to mcols
      read pdr,pdg,pdb,light(i)
      for j=0 to 63
        r(i*64+j)=(pdr/63*j)
        g(i*64+j)=(pdg/63*j)
        b(i*64+j)=(pdb/63*j)
      next j
  next i
  restore model_data
  read models
  for model=1 to models
    read points
    for point=1 to points
      read mfd,mfd,mfd
    next point
    read faces
    for face=1 to faces
        read mfd,mfd,mfd,mfd,mfd,mfd
    next face
    maxpoints=max(maxpoints,points)
    maxfaces=max(maxfaces,faces)
  next model
  restore model_data
  read models
  dim mx(models,maxpoints)
  dim my(models,maxpoints)
  dim mz(models,maxpoints)
  dim sx(maxpoints),sy(maxpoints)
  dim col(3),p(3)
  dim rx(maxpoints),ry(maxpoints),rz(maxpoints)
  dim points(models),faces(models)
  dim mfd1(models,maxfaces),mfd2(models,maxfaces)
  dim mfd3(models,maxfaces),mfd4(models,maxfaces,3)
  for model=1 to models
    read points(model)
    if points(model)<1 or points(model)>maxpoints then
print" Model data error - points - model="+str$(model)
      end
    fi
    for point=1 to points(model)
      read mx(model,point),my(model,point),mz(model,point)
    next point
    read faces(model)
    if faces(model)>maxfaces or faces(model)<0 then
print" Model data error - faces - model="+str$(model)
      end
    fi
    for face=1 to faces(model)
        read mfd
        if mfd<1 or mfd>points(model) then
print" Model face data error - model="+str$(model)
print" "+str$(face)+",p1"
          end
        fi
        mfd1(model,face)=mfd
        read mfd
        if mfd<1 or mfd>points(model) then
print" Model face data error - model="+str$(model)
print" "+str$(face)+",p2"
          end
        fi
        mfd2(model,face)=mfd
        read mfd
        if mfd<1 or mfd>points(model) then
print" Model face data error - model="+str$(model)
print" "+str$(face)+",p3"
          end
        fi
        mfd3(model,face)=mfd
for point=1 to 3
        read mfd
        if mfd<1 or mfd>mcols then
          if mfd<32 or mfd>(mcols+32) then
print" Model face data error - model="+str$(model)
print" "+str$(face)+",color"
            end
          fi
        fi
        mfd4(model,face,point)=mfd
next point
    next face
  next model
  restore object_data
  read max_objects
  if max_objects<1 then
    print" object data error - number of objects="+str$(max_objects)
    end
  fi
  dim ux1(max_objects,2),uy1(max_objects,2),uz1(max_objects,2)
  dim ux2(max_objects,2),uy2(max_objects,2),uz2(max_objects,2)
  dim ux3(max_objects,2),uy3(max_objects,2),uz3(max_objects,2)
  dim ox(max_objects),oy(max_objects),oz(max_objects)
  dim cols(max_objects)
  dim scale_x(max_objects),scale_y(max_objects),scale_z(max_objects)
  dim morph_target(max_objects)
  dim morph_count(max_objects),morph_speed(max_objects)
  dim mov_x(max_objects),mov_y(max_objects)
  dim mov_z(max_objects),mov_count(max_objects)
  dim scale_xc(max_objects),scale_yc(max_objects)
  dim scale_zc(max_objects),scale_count(max_objects)
  dim object_on(max_objects),link_done(max_objects)
  dim model(max_objects),link(max_objects,3)
  for object=1 to max_objects
    scale_x(object)=1
    scale_y(object)=1
    scale_z(object)=1
    read model(object),ox(object),oy(object),oz(object),cols(object)
    if model(object)<1 or model(object)>models then
      print" object data error - object="+str$(object)+" model="+str$(model(object))
      end
    fi
    for face=1 to faces(model(object))
for point=1 to 3
      c=cols(object)+mfd4(model(object),face,point)
      if c>32 c=c-32
      if c<1 or c>mcols then
        print" object data error - object="+str$(object)+" col offset?"
        end
      fi
next point
    next face
    if faces(model(object))>0 object_on(object)=1
    for uv=1 to 2
      ux1(object,uv)=0:uy1(object,uv)=0:uz1(object,uv)=1
      ux2(object,uv)=0:uy2(object,uv)=1:uz2(object,uv)=0
      ux3(object,uv)=1:uy3(object,uv)=0:uz3(object,uv)=0
    next uv
  next object
  restore link_data
  read links
  for link=1 to links
    read linked
    if linked<1 or linked>max_objects then
      print" link data error - link="+str$(link)+" no such object "+str$(linked)
      end
    fi
    for gld=1 to 3
      read link(linked,gld)
    next gld
    if link(linked,1)<1 or link(linked,1)>max_objects then
      print" link data error - link="+str$(link)+" no such object "+str$(link(linked,1))
      end
    fi
    if link(linked,2)<1 or link(linked,2)>points(model(link(linked,1))) then
      print" link data error - link="+str$(link)+" no such point "+str$(link(linked,2))
      end
    fi
  next link
  cam_ux1=0:cam_uy1=0:cam_uz1=1
  cam_ux2=0:cam_uy2=1:cam_uz2=0
  cam_ux3=1:cam_uy3=0:cam_uz3=0
  dim p1(max_poly),p2(max_poly)
  dim p3(max_poly)
  dim sort(max_objects+1)
  dim zds(max_objects+1)
  zds(0)=100000
  open window 640,512
'end setup/start calcs
  progfill=440/max_frames
  memfill=200/max_poly
  count=1
  loop=0
  repeat loop=loop+1
    setrgb 1,0,150,0
    fill rectangle 100,470 to 100+loop*progfill,480
    setrgb 1,200,200,200
    if loop=max_frames text 320,256,"press X to play","CC"
    rectangle 98,468 to 542,482
    if warning>0 setrgb 1,255,0,0
    if mode=1 goto switch
    ss=1-ss
label switch_ret
    gosub control
    goto draw_scene
label draw_scene_ret
    p1(count)=0
    count=count+1
    if mode=1 then
      if and(joy,1024)=1024 then
        repeat joy=peek("port1")
        until (and(joy,256)=0)
        repeat joy=peek("port1")
        until (and(joy,256)=256)
      fi
    fi
  until (loop=max_frames)
  repeat joy=peek("port1")
  until (joy=16384)
  clear window
  setdispbuf ss
  ss=1-ss
  setdrawbuf ss
  clear window
  repeat joy=peek("port1")
  until (joy=0)
  count=count-1
l=0
label pa
l=l+1
 p=p1(l)
 if p=0 goto s1
 x1=and(p,1023)-200
 y1=and(p,1047552)/1024-250
 c=p/1048576
 p=p2(l)
 x2=and(p,1023)-200
 y2=and(p,1047552)/1024-250
 setrgb 1,r(c),g(c),b(c)
 c=p/1048576
 setrgb 2,r(c),g(c),b(c)
 p=p3(l)
 c=p/1048576
 setrgb 3,r(c),g(c),b(c)
 x3=and(p,1023)-200
 y3=and(p,1047552)/1024-250
 gtriangle x1,y1 to x2,y2 to x3,y3
goto pa
label s1
 setdispbuf ss
 ss=1-ss
 setdrawbuf ss
 clear fill rectangle 0,0 to 640,512
if l<count goto pa
l=0
if or(fade_in,fade_out)=0 goto pa
joy=peek("port1")
if joy=16384 goto pa
repeat joy=peek("port1")
until (joy=16384)
setdispbuf ss
ss=1-ss
setdrawbuf ss
clear fill rectangle 0,0 to 640,512
repeat joy=peek("port1")
until (joy=0)
goto pa

label switch
    rectangle 98,452 to 152,248
    setrgb 1,0,0,150
    fill rectangle 100,450 to 150,450-count*memfill
    setrgb 1,250,250,250
    fram$="frame:"+str$(loop)
    text 360,450,fram$
    tri$="triangles:"+str$(tri_count)
    text 200,450,tri$
    setdispbuf ss
    ss=1-ss
    setdrawbuf ss
    clear window
    joy=peek("port1")
goto switch_ret

label lock_camera
  cam_ux1=0:cam_uy1=0:cam_uz1=1
  cam_ux2=0:cam_uy2=1:cam_uz2=0
  cam_ux3=1:cam_uy3=0:cam_uz3=0
  if look=0 look=lock
  tx=ox(look)-cam_x
  ty=oy(look)-cam_y
  tz=oz(look)-cam_z
  rx=cam_ux3*tx+cam_ux2*ty+cam_ux1*tz
  ry=cam_uy3*tx+cam_uy2*ty+cam_uy1*tz
  rz=cam_uz3*tx+cam_uz2*ty+cam_uz1*tz
  a=mod(360+(atan(rx,rz)/pi*180),360)
  hd=sqrt(rx^2+rz^2)
  b=mod(360-(atan(ry,hd)/pi*180),360)
  rot_cam(b,a,0)
  if look>0 and look<>lock lock=0
  look=0
goto lock_camera_ret  

label draw_scene
  object_count=0
  zds(1)=0
  if cam_count>0 then
    cam_x=cam_x+mov_cam_x
    cam_y=cam_y+mov_cam_y
    cam_z=cam_z+mov_cam_z
    cam_count=cam_count-1
  fi
  object=0
  repeat object=object+1
    if mov_count(object)>0 then
      ox(object)=ox(object)+mov_x(object)
      oy(object)=oy(object)+mov_y(object)
      oz(object)=oz(object)+mov_z(object)
      mov_count(object)=mov_count(object)-1
    fi
    morph_target=morph_target(object)
    if morph_target>0 then
        morph_count=morph_count(object)
morph_count(object)=morph_count-morph_speed(object)
      if morph_count(object)<=0 then
        model(object)=morph_target
        morph_target(object)=0
      fi
    fi
    if scale_count(object)>0 then
      scale_x(object)=scale_x(object)+scale_xc(object)
      scale_y(object)=scale_y(object)+scale_yc(object)
      scale_z(object)=scale_z(object)+scale_zc(object)
      scale_count(object)=scale_count(object)-1
    fi
    link_done(object)=0
  until (object=max_objects)
  repeat
    link_count=0
    object=0
    repeat object=object+1
      link_object=link(object,1)
      if link_object>0 and link_done(object)=0 then
if link_done(link_object)=1 or link(link_object,1)=0 then
          link_object=link(object,1)
          model=model(link_object)
          point=link(object,2)
    ux1=ux1(link_object,1)
    uy1=uy1(link_object,1):uz1=uz1(link_object,1)
    ux2=ux2(link_object,1)
    uy2=uy2(link_object,1):uz2=uz2(link_object,1)
    ux3=ux3(link_object,1)
    uy3=uy3(link_object,1):uz3=uz3(link_object,1)
x1=uy3*uz2-uy2*uz3:y1=ux2*uz3-uz2*ux3:z1=uy2*ux3-ux2*uy3
x2=uy1*uz3-uy3*uz1:y2=uz1*ux3-ux1*uz3:z2=ux1*uy3-uy1*ux3
x3=uz1*uy2-uy1*uz2:y3=ux1*uz2-uz1*ux2:z3=ux2*uy1-ux1*uy2
          tx=mx(model,point)
          ty=my(model,point)
          tz=mz(model,point)
          morph_target=morph_target(link_object)
          if morph_target>0 then
            morph_count=morph_count(link_object)
            txm=mx(morph_target,point)
            tym=my(morph_target,point)
            tzm=mz(morph_target,point)
            tx=(tx-txm)/100*morph_count+txm
            ty=(ty-tym)/100*morph_count+tym
            tz=(tz-tzm)/100*morph_count+tzm
          fi
          tx=tx*scale_x(link_object)
          ty=ty*scale_y(link_object)
          tz=tz*scale_z(link_object)
          ox(object)=ox(link_object)+x3*tx+y3*ty+z3*tz
          oy(object)=oy(link_object)+x2*tx+y2*ty+z2*tz
          oz(object)=oz(link_object)+x1*tx+y1*ty+z1*tz
          if and(link(object,3),2)=2 then
            scale_x(object)=scale_x(link_object)
            scale_y(object)=scale_y(link_object)
            scale_z(object)=scale_z(link_object)
          fi
          if and(link(object,3),1)=1 then
            lx1=ux1(object,2)
            ly1=uy1(object,2)
            lz1=uz1(object,2)
            lx2=ux2(object,2)
            ly2=uy2(object,2)
            lz2=uz2(object,2)
            lx3=ux3(object,2)
            ly3=uy3(object,2)
            lz3=uz3(object,2)
            ux1(object,1)=ux1*lx3+uy1*lx2+uz1*lx1
            uy1(object,1)=ux1*ly3+uy1*ly2+uz1*ly1
            uz1(object,1)=ux1*lz3+uy1*lz2+uz1*lz1
            ux2(object,1)=ux2*lx3+uy2*lx2+uz2*lx1
            uy2(object,1)=ux2*ly3+uy2*ly2+uz2*ly1
            uz2(object,1)=ux2*lz3+uy2*lz2+uz2*lz1
            ux3(object,1)=ux3*lx3+uy3*lx2+uz3*lx1
            uy3(object,1)=ux3*ly3+uy3*ly2+uz3*ly1
            uz3(object,1)=ux3*lz3+uy3*lz2+uz3*lz1
          fi
          link_done(object)=1
        else
          link_count=link_count+1
        fi
      fi
    until (object=max_objects)
  until(link_count=0)
  if lock>0 or look>0 goto lock_camera
label lock_camera_ret
  object=0
  repeat object=object+1
    if object_on(object)=0 goto object_offscreen
    tx=ox(object)-cam_x
    ty=oy(object)-cam_y
    tz=oz(object)-cam_z
    rz=cam_uz3*tx+cam_uz2*ty+cam_uz1*tz
    if rz<=80 goto object_offscreen
    rx=cam_ux3*tx+cam_ux2*ty+cam_ux1*tz
    ry=cam_uy3*tx+cam_uy2*ty+cam_uy1*tz
    sz=sqrt(rx^2+ry^2+rz^2)
    sx=rx/(sz/fl)
    if abs(sx)>370 goto object_offscreen
    sy=ry/(sz/fl)
    if abs(sy)>306 goto object_offscreen
        pos=0
        repeat
            pos=pos+1 
        until (zds(pos)<sz)
        object_count=object_count+1
        j=object_count
        repeat
            sort(j+1)=sort(j)
            zds(j+1)=zds(j) 
            j=j-1
        until (j<pos)
        sort(pos)=object
        zds(pos)=sz
label object_offscreen
  until (object=max_objects)
  if object_count=0 goto draw_scene_ret
  sort=0
  tri_count=0
  repeat sort=sort+1
    object=sort(sort)
    model=model(object)
    ux1=ux1(object,1):uy1=uy1(object,1):uz1=uz1(object,1)
    ux2=ux2(object,1):uy2=uy2(object,1):uz2=uz2(object,1)
    ux3=ux3(object,1):uy3=uy3(object,1):uz3=uz3(object,1)
x1=uy3*uz2-uy2*uz3:y1=ux2*uz3-uz2*ux3:z1=uy2*ux3-ux2*uy3
x2=uy1*uz3-uy3*uz1:y2=uz1*ux3-ux1*uz3:z2=ux1*uy3-uy1*ux3
x3=uz1*uy2-uy1*uz2:y3=ux1*uz2-uz1*ux2:z3=ux2*uy1-ux1*uy2
    point=0
    ox=ox(object)-cam_x
    oy=oy(object)-cam_y
    oz=oz(object)-cam_z
    p_m=points(model)
    morph_target=morph_target(object)
    repeat point=point+1
      tx=mx(model,point)
      ty=my(model,point)
      tz=mz(model,point)
      if morph_target>0 then
        morph_count=morph_count(object)
        txm=mx(morph_target,point)
        tym=my(morph_target,point)
        tzm=mz(morph_target,point)
        tx=(tx-txm)/100*morph_count+txm
        ty=(ty-tym)/100*morph_count+tym
        tz=(tz-tzm)/100*morph_count+tzm
      fi
      tx=tx*scale_x(object)
      ty=ty*scale_y(object)
      tz=tz*scale_z(object)
      ntx=ox+x3*tx+y3*ty+z3*tz
      nty=oy+x2*tx+y2*ty+z2*tz
      ntz=oz+x1*tx+y1*ty+z1*tz
      rx=cam_ux3*ntx+cam_ux2*nty+cam_ux1*ntz
      ry=cam_uy3*ntx+cam_uy2*nty+cam_uy1*ntz
      rz=cam_uz3*ntx+cam_uz2*nty+cam_uz1*ntz
      rx(point)=rx
      ry(point)=ry
      rz(point)=rz
      sz=sqrt(rx^2+ry^2+rz^2)/fl
      sx(point)=320+rx/sz
      sy(point)=256-ry/sz
    until (point=p_m)
    face=0
    f_m=faces(model)
    repeat face=face+1
      p1=mfd1(model,face)
      p2=mfd2(model,face)
      p3=mfd3(model,face)
      sx1=sx(p1):sy1=sy(p1)
      sx2=sx(p2):sy2=sy(p2)
      sx3=sx(p3):sy3=sy(p3)
if (sx2-sx1)*(sy3-sy1)-(sx3-sx1)*(sy2-sy1)<0 goto no_face
      vx1=rx(p2)-rx(p1)
      vy1=ry(p2)-ry(p1)
      vz1=rz(p2)-rz(p1)
      vx2=rx(p3)-rx(p1)
      vy2=ry(p3)-ry(p1)
      vz2=rz(p3)-rz(p1)
      vx=vy1*vz2-vz1*vy2
      vy=vz1*vx2-vx1*vz2
      vz=vx1*vy2-vy1*vx2
      vl=sqrt(vx^2+vy^2+vz^2)
      vx=vx/vl
      vy=vy/vl
      vz=vz/vl
      p(1)=p1:p(2)=p2:p(3)=p3
      for point=1 to 3
        col=mfd4(model,face,point)+cols(object)
        half_b=1
        if col>31 then
          col=col-32
          half_b=2
        fi
        shade=1
        if and(light(col),3)>0 then
d1=sqrt(rx(p(point))^2+ry(p(point))^2+rz(p(point))^2)
d2=sqrt((rx(p(point))+vx)^2+(ry(p(point))+vy)^2+(rz(p(point))+vz)^2)
          shade=d1-d2
          if and(light(col),3)=2 shade=shade*ref+max(tan(shade*1.5708)/bright,0)
          if and(light(col),3)=3 shade=asin(shade)/pi*2
        shade=.15+max(min(shade/half_b,1),0)*.85
        fi
        if loop<fade_in and and(light(col),4)=0 shade=shade/fade_in*loop
if max_frames-loop<fade_out and and(light(col),8)=0 shade=shade/fade_out*(max_frames-loop)
        col(point)=col*64+shade*63
setrgb point,r(col(point)),g(col(point)),b(col(point))
      next point
      if mode=1 gtriangle sx1,sy1 to sx2,sy2 to sx3,sy3
sx1=max(min(sx1+200,1020),0):sy1=max(min(sy1+250,1020),0)
sx2=max(min(sx2+200,1020),0):sy2=max(min(sy2+250,1020),0)
sx3=max(min(sx3+200,1020),0):sy3=max(min(sy3+250,1020),0)
p1(count)=int(sx1)+(int(sy1))*1024+int(col(1))*1048576
p2(count)=int(sx2)+(int(sy2))*1024+int(col(2))*1048576
p3(count)=int(sx3)+(int(sy3))*1024+int(col(3))*1048576
      count=min(count+1,max_poly-1)
      tri_count=tri_count+1
label no_face
    until (face=f_m)
  until (sort=object_count)
goto draw_scene_ret

sub morph(object,target,frmes)
  if object<1 or object>max_objects then
    close window
    print" Control error - 'morph' object="+str$(object)
    end
  fi
  if target<1 or target>models then
    close window
    print" Control error - 'morph' target="+str$(target)
    end
  fi
  if morph_count(object)<=0 then
    if frmes<1 then
      model(object)=target
    else
      morph_target(object)=target
      morph_count(object)=100
      morph_speed(object)=100/frmes
    fi
  fi
end sub

sub scale(object,movx,movy,movz)
  if object<1 or object>max_objects then
    close window
    print" Control error - 'scale' object="+str$(object)
    end
  fi
  if scale_count(object)<=0 then
    scale_x(object)=scale_x(object)*movx
    scale_y(object)=scale_y(object)*movy
    scale_z(object)=scale_z(object)*movz
  fi
end sub

sub scale_to(object,movx,movy,movz,frmes)
  if object<1 or object>max_objects then
    close window
print" Control error - 'scale_to' object="+str$(object)
    end
  fi
  if scale_count(object)<=0 then
    if frmes<1 then
      scale_x(object)=movx
      scale_y(object)=movy
      scale_z(object)=movz
    else
      scale_xc(object)=(movx-scale_x(object))/frmes
      scale_yc(object)=(movy-scale_y(object))/frmes
      scale_zc(object)=(movz-scale_z(object))/frmes
      scale_count(object)=frmes
    fi
  fi
end sub

sub rot_obj(object,movx,movy,movz)
    if object<1 or object>max_objects then
    close window
    print" Control error - 'rot_obj' object="+str$(object)
    end
  fi
  movx=mod(360-movx,360)
  movy=mod(360-movy,360)
  movz=mod(360+movz,360)
  snb=sn(movx*16):csb=cs(movx*16)
  sna=sn(movy*16):csa=cs(movy*16)
  snc=sn(movz*16):csc=cs(movz*16)
  uv=1
  if and(link(object,3),1)=1 uv=2
ux1=ux1(object,uv):uy1=uy1(object,uv):uz1=uz1(object,uv)
ux2=ux2(object,uv):uy2=uy2(object,uv):uz2=uz2(object,uv)
ux3=ux3(object,uv):uy3=uy3(object,uv):uz3=uz3(object,uv)
    tx=ux1*csa+uz1*sna
    tz=uz1*csa-ux1*sna
    uz1(object,uv)=tz*csb+uy1*snb
    ty=uy1*csb-tz*snb
    ux1(object,uv)=tx*csc+ty*snc
    uy1(object,uv)=ty*csc-tx*snc
    tx=ux2*csa+uz2*sna
    tz=uz2*csa-ux2*sna
    uz2(object,uv)=tz*csb+uy2*snb
    ty=uy2*csb-tz*snb
    ux2(object,uv)=tx*csc+ty*snc
    uy2(object,uv)=ty*csc-tx*snc
    tx=ux3*csa+uz3*sna
    tz=uz3*csa-ux3*sna
    uz3(object,uv)=tz*csb+uy3*snb
    ty=uy3*csb-tz*snb
    ux3(object,uv)=tx*csc+ty*snc
    uy3(object,uv)=ty*csc-tx*snc
end sub

sub rot_cam(movx,movy,movz)
  movx=mod(360-movx,360)
  movy=mod(360-movy,360)
  movz=mod(360+movz,360)
  snb=sn(movx*16):csb=cs(movx*16)
  sna=sn(movy*16):csa=cs(movy*16)
  snc=sn(movz*16):csc=cs(movz*16)
  tx=cam_ux1*csa+cam_uz1*sna
  tz=cam_uz1*csa-cam_ux1*sna
  cam_uz1=tz*csb+cam_uy1*snb
  ty=cam_uy1*csb-tz*snb
  cam_ux1=tx*csc+ty*snc
  cam_uy1=ty*csc-tx*snc
  tx=cam_ux2*csa+cam_uz2*sna
  tz=cam_uz2*csa-cam_ux2*sna
  cam_uz2=tz*csb+cam_uy2*snb
  ty=cam_uy2*csb-tz*snb
  cam_ux2=tx*csc+ty*snc
  cam_uy2=ty*csc-tx*snc
  tx=cam_ux3*csa+cam_uz3*sna
  tz=cam_uz3*csa-cam_ux3*sna
  cam_uz3=tz*csb+cam_uy3*snb
  ty=cam_uy3*csb-tz*snb
  cam_ux3=tx*csc+ty*snc
  cam_uy3=ty*csc-tx*snc
end sub

sub mov_obj(object,movx,movy,movz)
  if object<1 or object>max_objects then
    close window
    print" Control error - 'mov_obj' object="+str$(object)
    end
  fi
  if mov_count<=0 then
    ux1=ux1(object,1):uy1=uy1(object,1):uz1=uz1(object,1)
    ux2=ux2(object,1):uy2=uy2(object,1):uz2=uz2(object,1)
    ux3=ux3(object,1):uy3=uy3(object,1):uz3=uz3(object,1)
x1=uy3*uz2-uy2*uz3:y1=ux2*uz3-uz2*ux3:z1=uy2*ux3-ux2*uy3
x2=uy1*uz3-uy3*uz1:y2=uz1*ux3-ux1*uz3:z2=ux1*uy3-uy1*ux3
x3=uz1*uy2-uy1*uz2:y3=ux1*uz2-uz1*ux2:z3=ux2*uy1-ux1*uy2
    ix=x3*movx+y3*movy+z3*movz
    iy=x2*movx+y2*movy+z2*movz
    iz=x1*movx+y1*movy+z1*movz
    ox(object)=ox(object)+ix
    oy(object)=oy(object)+iy
    oz(object)=oz(object)+iz
  fi
end sub

sub mov_obj_rl(object,movx,movy,movz)
  if object<1 or object>max_objects then
    close window
print" Control error - 'mov_obj_rl' object="+str$(object)
    end
  fi
  if mov_count<=0 then
    ox(object)=ox(object)+movx
    oy(object)=oy(object)+movy
    oz(object)=oz(object)+movz
  fi
end sub

sub mov_obj_to(object,movx,movy,movz,frmes)
  if object<1 or object>max_objects then
    close window
print" Control error - 'mov_obj_to' object="+str$(object)
    end
  fi
  if mov_count(object)<=0 then
    if frmes<1 then
      ox(object)=movx
      oy(object)=movy
      oz(object)=movz
    else
      mov_x(object)=(movx-ox(object))/frmes
      mov_y(object)=(movy-oy(object))/frmes
      mov_z(object)=(movz-oz(object))/frmes
      mov_count(object)=frmes
    fi
  fi
end sub

sub mov_cam(movx,movy,movz)
  if cam_count<=0 then
    x1=cam_uy3*cam_uz2-cam_uy2*cam_uz3
    y1=cam_ux2*cam_uz3-cam_uz2*cam_ux3
    z1=cam_uy2*cam_ux3-cam_ux2*cam_uy3
    x2=cam_uy1*cam_uz3-cam_uy3*cam_uz1
    y2=cam_uz1*cam_ux3-cam_ux1*cam_uz3
    z2=cam_ux1*cam_uy3-cam_uy1*cam_ux3
    x3=cam_uz1*cam_uy2-cam_uy1*cam_uz2
    y3=cam_ux1*cam_uz2-cam_uz1*cam_ux2
    z3=cam_ux2*cam_uy1-cam_ux1*cam_uy2
    ix=x3*movx+y3*movy+z3*movz
    iy=x2*movx+y2*movy+z2*movz
    iz=x1*movx+y1*movy+z1*movz
    cam_x=cam_x+ix:cam_y=cam_y+iy:cam_z=cam_z+iz
  fi
end sub

sub mov_cam_rl(movx,movy,movz)
  if cam_count<=0 then
    cam_x=cam_x+movx
    cam_y=cam_y+movy
    cam_z=cam_z+movz
  fi
end sub

sub mov_cam_to(movx,movy,movz,frmes)
  if cam_count<=0 then
    if frmes<1 then
      cam_x=movx
      cam_y=movy
      cam_z=movz
    else
      mov_cam_x=(movx-cam_x)/frmes
      mov_cam_y=(movy-cam_y)/frmes
      mov_cam_z=(movz-cam_z)/frmes
      cam_count=frmes
    fi
  fi
end sub

sub lock(lock_cam)
  if lock_cam<0 or lock_cam>max_objects then
    close window
    print" Control error - 'lock' object="+str$(lock_cam)
    end
  fi
  lock=lock_cam
end sub

sub look(lock_cam)
  if lock_cam<1 or lock_cam>max_objects then
    close window
    print" Control error - 'look' object="+str$(lock_cam)
    end
  fi
  look=lock_cam
end sub

sub obj_on(object,lock)
  if object<1 or object>max_objects then
    close window
    print" Control error - 'obj_on' object="+str$(object)
    end
  fi
  object_on(object)=lock
end sub




