Challenge: 
Winner?: 
Yes
Code Snippet: 
Sync On:Sync Rate 0:Autocam Off
Dim Keys(14)
Dim fa(14) as Float
Global mmx as Float
Global mmy as Float
Global mmz as Float
Global udk as Float
Global n#
Global cFlag as Integer
Global fFlag as Integer

Restore Keys
For j=1 to 14
   Read Keys(j)
Next j

Restore fangles
For j=1 to 14
   Read fa(j)
Next j

Make Object Sphere 10,15
Scale Limb 10,0,120,30,80
make object Cylinder 11,1
Scale Object 11,300,600,300
Pitch Object Down 11,90
Offset Limb 11,0,0,.5,0
Fix Object Pivot 11
Make Mesh From Object 11,11
Delete Object 11

local i as float
For i= 1.0 to 15.0 step 3.0
   Add Limb 10,i,11
   Add Limb 10,i+1,11
   Link Limb 10,i,i+1
   x#=Sin(30.0-(i*6.0))*12.0-.5
   z#=Cos(30.0-(i*6.0))*10.0-8.0
   Offset Limb 10,i,x#,0,z#
   Offset Limb 10,i+1,0,0,5
   Rotate Limb 10,i,5,20-(i*5),0
   If i+2<>15
      Add Limb 10,i+2,11
      Link Limb 10,i+1,i+2
      Offset Limb 10,i+2,0,0,5
   Endif
Next i
Offset Limb 10,13,6,0,-3
Rotate Limb 10,13,0,90,0
Set Object Cull 10,0
Position Object 10,0,30,50
Set Object Collision OFf 10
Make Object Sphere 11,15,10,10
Scale Object 11,120,0.02,80
Color Object 11,0
Set Object Ambience 11,0
Set Object Emissive 11,0
Set oBject Collision Off 11
Make Object Sphere 20,6
Position Object 20,0,0,60
Set object Collision Off 20
`Make_Collision_Object("Sphere",20,6.3,6.3,6.3,8,8)
Make Object Plain 2,110,160
Pitch Object Down 2,90
Color Object 2,Rgb(0,200,0)
Set Object Emissive 2,rgb(0,20,0)
Position Object 2,0,-4.2,100
Set Object Collision Off 2
Position Camera 0,30,0
`Pitch Camera Down 20
t1=timer()
Do
   Object_Wrangling(20)
   Hand_Wrangling(10)
   Clear Entry Buffer
   Set Cursor 0,0
   Print "FPS=";Screen FPS()
   Print "Est. Max. FPS=";1000/(timer()-t1+1)
   Point Camera 0,Object Position X(10),Object Position Y(10)-5,Object Position Z(10)
   Sync
   t1=timer()
Loop

Function Object_Wrangling(ObjectID)
   If Object Position Y(ObjectID)>0
      Position Object ObjectID, Object Position X(ObjectID),Object Position Y(ObjectID)-.2,Object Position Z(ObjectID)
   Endif
   c#=Check_Collision("limb",ObjectID,0,10,5,3)*.8 `The *.8 is hand-to-ball friction. Check_Collision returns 1 if collision is occuring or 0 if not.
   if c#>0
      Position Object ObjectID,fpos(ObjectID*20,0)+(mmx*c#),fpos(ObjectID*20,1)+(udk*c#),fpos(ObjectID*20,2)+(mmy*c#) `Here we reposition the object and addjust based on movement of the hand modified by the friction
   Endif
   If Object Position Y(ObjectID)<0
      Position Object ObjectID, Object Position X(ObjectID),0,Object Position Z(ObjectID)
   Endif
   If Object Position X(ObjectID)<-50
      Position Object ObjectID,-50,Object Position Y(ObjectID),Object Position Z(ObjectID)
   Endif
   If Object Position X(ObjectID)>50
      Position Object ObjectID,50,Object Position Y(ObjectID),Object Position Z(ObjectID)
   Endif
   If Object Position Z(ObjectID)<20
      Position Object ObjectID,Object Position X(ObjectID),Object Position Y(ObjectID),20
   Endif
   If Object Position Z(ObjectID)>180
      Position Object ObjectID,Object Position X(ObjectID),Object Position Y(ObjectID),180
   Endif
EndFunction

Function Hand_Wrangling(ObjectID)
   mmx=MousemoveX()
   mmx=mmx*.2
   mmy=-MouseMoveY()
   mmy=mmy*.2
   mmz=MouseMoveZ()
   mmz=mmz*.1
   IF abs(mmx)>1
      mmx=mmx*(1.0/abs(mmx))
   Endif
   if Abs(mmy)>1
      mmy=mmy*(1.0/abs(mmy))
   Endif
   udk=(Upkey()-DownKey())
   udk=udk*.2
   ox#=Object Position X(ObjectID):oy#=Object Position Y(ObjectID):oz#=Object Position Z(ObjectID)
   Position Object ObjectID,Object Position X(ObjectID)+mmx,Object POsition y(ObjectID)+udk,Object Position Z(ObjectID)+mmy
   Pitch Object Down ObjectID,mmz
   Position Object ObjectID+1,Object Position X(ObjectID),-4,Object Position Z(ObjectID)
   Fingers()
EndFunction

Function Fingers()
   Local up as float
   If MouseClick()=0 Then ExitFunction
   Dim Limbs(14)
   up=((Mouseclick()=2)-(MouseClick()=1))*4
   n=Check_Collision("limb",10,0,20,1,4)
   fFlag=(fFlag=0)
   For i=1+fFlag to 13+fFlag
      Limbs(i)=Check_Collision("limb",10,i,20,2,4)
      n=n+Limbs(i)
      up=up*(n<1 or Limbs(i)=0)
      Rotate Limb 10,i,Limb Angle X(10,i)+KeyState(Keys(i))*up*(Limb Angle X(10,i)+up>0 and Limb Angle X(10,i)+up<80),fa(i),0
   Next i
Endfunction


`This initializes our mesh for collision. Two types available currently are box or cube, and sphere.
`TargetID assumes an object, but one is not actually required. In planned updates, the mesh may be a clone of the target object, so one would be required.
`SizeX#/Y#/Z# are the sizes of the collision object. Currently, the collision are does not rotate with the object.
`Rows and Cols are only used for the Sphere type object. They are ingnored for the box/cube object, but must still be supplied.
`The smaller these values the faster the check, but is less "round" and less accurate for collision checks. Larger spheres may miss collisions if the rows/cols settings are too low.
Function Make_Collision_Object(Type$,TargetID,SizeX#,SizeY#,SizeZ#,rows,cols)
Local ObjectID as DWord
ObjectID=TargetID+50000
If Object Exist(ObjectID)
   Delete Object ObjectID
Endif
Select lower$(type$)
   Case "sphere"
      Make Object Sphere ObjectID,1,rows,cols
   Endcase
   Case "box","cube"
      Make Object Cube ObjectID,1
   Endcase
   Case Default
      Exit Prompt "Error","Make_Collision_Object Type$ '"+Type$+"' not recognized."
      end
   Endcase
EndSelect
If lower$(type$)<>"polygon"
   Scale Object ObjectID,Sizex#*100.0,Sizey#*100.0,Sizez#*100.0
Endif
Make Mesh from Object ObjectID,ObjectID
Delete Object ObjectID
EndFunction


`This returns an offset point that reflects an average "best" position away from all collisions with a particular object. This is very useful for complex objects.
`ObjectID must be the same value used to initialize a collision object (see Make_Collision_Object())
`TargetID is the object check a collision against.
`Accuracy# is value I am still playing with. It is intended to translate into a step-value for cycling through the indexes. Currently it simply divides 100  by accuracy# to get the step value.
`Ultimately, accuracy reflects the balance between speed (fewer checks) and accuracy (more checks).
`Cycles is another way to optimise balance the speed and accuracy. increasing the cycles allows the accuracy to be lower increasing the speed, but will cause a vibration. The higher the cycle number, the more vibration.
Function Check_Collision(Type$,ObjectID as DWord,LimbID as DWord,TargetID as DWord,accuracy#,cycles)
arry=ObjectID*20+LimbID
if Array Count(cflag())<arry
   Dim cFlag(arry) as Integer
   Dim fpos(arry,2) as Float
   Dim n(arry) as Float
Endif
Local mesh as DWord
Select Lower$(type$)
   Case "object"
      Mesh=ObjectID+50000
      If Mesh Exist(ObjectID+50000)=0
         Exit Prompt "Error","Check_Collision(): Collision Object not defined. Use Make_Collision_Object() to define."
         End
      Endif
      Lock VertexData For Mesh Mesh
      ox#=Object Position X(ObjectID)
      oy#=Object Position Y(ObjectID)
      oz#=Object Position Z(ObjectID)
   EndCase
   Case "limb"
      If Limb Exist(ObjectID,LimbID)=0
         Exit Prompt "Error","Check_Collision():Limb does not exist. ObjectID and LimbID must be valid."
         End
      Endif
      Lock VertexData for Limb ObjectID,LimbID
      ox#=Limb Position X(ObjectID,LimbID)
      oy#=Limb Position Y(ObjectID,LimbID)
      oz#=Limb Position Z(ObjectID,LimbID)
   EndCase
   Case Default
      Exit Prompt "Error","Check_Collision(): Invalid object type. Use 'Limb' or 'Object'."
      End
   EndCase
Endselect
VIC=(Get Vertexdata Index Count()-cFlag(arry))-1
if ObjectID=20 Then Print "Vertecies=";VIC+cFlag(arry)
accuracy#=accuracy#/100.0
   n(arry)=1
If cFlag(arry)=0
   fpos(arry,0)=ox#
   fpos(arry,1)=oy#
   fpos(arry,2)=oz#
Endif
st=1.0/accuracy#
For i = 0+cFlag to VIC+cFlag(arry) step st
   for j = 0 to 2
      ij=i+j
      v=Get IndexData(ij)
      vx#=Get VertexData Position X(v)
      vy#=Get VertexData Position Y(v)
      vz#=Get VertexData Position Z(v)
      d#=Intersect Object(TargetID,ox#,oy#,oz#,vx#+ox#,vy#+oy#,vz#+oz#)
      if d#>0
         Null=Make Vector3(1)
         Set Vector3 1,vx#,vy#,vz#
         d2#=Length Vector3(1)
         id2#=d2#-d#
         Multiply Vector3 1,-(id2#/d2#)
         fpos(arry,0)=fpos(arry,0)+(ox#+X Vector3(1))*id2#
         fpos(arry,1)=fpos(arry,1)+(oy#+Y Vector3(1))*id2#
         fpos(arry,2)=fpos(arry,2)+(oz#+Z Vector3(1))*id2#
         n(arry)=n(arry)+id2#
      Endif
   next j
Next i
cFlag(arry)=cFlag(arry)+1
if cFlag(arry)>cycles
   cFlag(arry)=0
Endif
fpos(arry,0)=fpos(arry,0)/n(arry)
fpos(arry,1)=fpos(arry,1)/n(arry)
fpos(arry,2)=fpos(arry,2)/n(arry)
Unlock VertexData

Hit=(n(arry)>1)
EndFunction Hit

Keys:
Data 47,33,19,46,32,18,45,31,17,44,30,16,57,48

Fangles:
Data 15,0,0,0,0,0,-15,0,0,-30,0,0,90,0