aUCBLogo Demos and Tests / shuttle
			
				
			
			
;   This is a MSWLogo 3D example where I have written a simple ".3DV"
;   file viewer. 3DV is a simple public domain format for 3D Vectors.
;   Do not confuse how this "Shuttle" database was built.
;   The vectors were not built with MSWLogo (although they could be).
;   Do not confuse how you "normally" build 3D objects in MSWLogo.
;   You normally build 3D object just like you always built them
;   in 2D, by moving the turtle around.
 
;   This example was just done for a completeness test. The data is
;   absolute and uses SETXYZ for all drawing. No turtle.
;   It's a good example of how to use file and Array operations.
;   It's also an example of seeing how I took "foreign" data from the
;   internet and used it in logo. There is TONS of "data" out their.
;   Mars weather statistics, continental drift statistics, etc. that
;   can be used for all sorts of projects. (George Mills)
;   I`ve added the 3DV_display_solid procedure (Andreas Micheler).
be shuttle
   local [start finish command vertex]
   ht
   perspective
   cs
;   setEye {400 400 600}{0 0 0}{0 1 0}
   
   command=[]
   vertex=[]
   3DV_load "shuttle.3dv &command &vertex   ; Load Shuttle Vectors
   pr [ESC stops, + - changes speed]
   
   start=timefine   ; Time and Display Shuttle
   setMaterialSpecular HSB 70 0.5 0.5
   setMaterialShininess 10
   setLightSpotExponent 2
   setPenColor 7
   setScreenColor 0
;   3DV_display_wireframe command vertex
   3DV_display_solid command vertex
   finish=timefine-start
   show (sentence count command "3D "Commands "in finish "seconds)   
      ; It takes about 90 seconds on a PII 300
      
   rotatescene2
end
be 3DV_load file &command &vertex
   openRead file         ; Open Vectors Commands
   setReader file
   vertices=first readList      ; Get # of vertices (1st record of file)
   vertex=(array vertices 1)      ; Now build a "Vertex" array based on # of vertices
   repeat vertices
   [            ; Now read in each "Vertex". Format [X Y Z]
      vertex.repcount=readList/50+[0 0 200]
   ]
   commands=first readList      ; Get # of "commands" (comes after all vertices)
   command=(array commands 1)   ; Now build a "Command" array based on # of commands
   repeat commands
   [            ; Now read in each "Command". Format [Vertex_Index Color]
      command.repcount=readList
   ]
   setReader []            ; Done
   close file
end
be 3DV_display_wireframe command vertex
   local [vtx cmd]
   repeat count command
   [
      cmd=command.repcount ; Get a command. 
                  ; Format [VertexIndex Color] Color = 0 means "Move"
      vtx=vertex.(first cmd)   ; Get the vertex. Format [X Y Z]
      ifelse (last cmd) == 0
      [   pu         ; If color 0 then Move
      ][   pd         ; else Draw (I'm ingoring the color, not RGB Yuck)
      ]
      setPosXYZ vtx         ; Move or draw to the vertex
   ]
end
be 3DV_display_solid command vertex
   local [points cmd commands vertices]
   points=[]
   commands=count command
   vertices=count vertex
   penup
   enableCylinderLines
   setPenSize [2 2]
   repeat commands
   [   cmd=int command.repcount   ; Get a command. 
                  ; Format [VertexIndex Color] Color = 0 means "Move"
      vtx=vertex.(first cmd)   ; Get the vertex. Format [X Y Z]
      if (last cmd) == 0
      [            ; If color = 0 ...
         ifelse (count points) == 0
         [         ; ..and no points then just move
            setPosXYZ vtx
         ][   if (count points) == 2
            [            ; ...and 2 points then connect them
               setPosXYZ first points  
               pd  setPosXYZ last points  pu
            ]
            if (count points) > 2
            [            ; ...and 3 or more points then
               repeat (count points)-1
               [         ; connect them...
                  setPosXYZ points.repcount
                  pd  setPosXYZ points.(repcount+1)  pu
               ]
               ;setPosXYZ first points  
               ;setPosXYZ last points
               pd
               while [not empty? points]
               [   normal=cross points.1-points.2 points.2-points.3
                  if (Norm normal) > 1e-1
                  [   break
                  ]
                  points=bf points
               ]
               PolyStart         ; and make a polygon out of them.
               foreach points
               [   setPosXYZ ?
               ]
               PolyEnd
               pu
            ]
         ]
         points=[]      ; finally clear the old points
      ]
      queue "points vtx         ; add the new vertex to the points list
   ]
end