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