It's a little tough to get the height right since there is no shadow. What happens when you "squash" the ball? It should pop-up or move to the side. But I gather from your comment it's not. I'll add a "shadow" to help align things better.
Edit: Okay, here's the shadow. I also added another feature to help with frame-rate vs. accuracy. I will be working on getting the limbs to detect collisions with the sphere and the "floor" next.
Edit2: Added beginning of hand-to-sphere collision detection. If you try to "crush" the sphere in the hand, the fingers will stop. There is some overlap due to the accuracy vs. speed factor, but you should notice that the hand won't close completely if the ball is inside it. If you have some spare fps, you change the accuracy setting for the limbs and it should work even better. Also made a few other minor improvements. 1) Mousewheel will pitch the hand.
Note: On my pc, I am getting about 90 fps when not moving the fingers and about 50 fps when the fingers are moving. I know on my pc at work, the FPS would be crawling. Adjust (decrease) the accuracy values to increase the FPS as needed.
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
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.1,6.1,6.1,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
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
Position Object 10,Object Position X(10)+mmx,Object POsition y(10)+udk,Object Position Z(10)+mmy
Pitch Object Down 10,mmz
Position Object 11,Object Position X(10),-4,Object Position Z(10)
Object_Wrangling(20)
Fingers()
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)-.3,Object Position Z(ObjectID)
Endif
c#=Check_Collision("object",ObjectID,0,10,6,1)*.8 `The *.8 is our friction. Check_Collision returns 1 if collision is occuring or 0 if not.
Position Object ObjectID,fpos(0)+(mmx*c#),fpos(1)+(udk*c#),fpos(2)+(mmy*c#) `Here we reposition the object and addjust based on movement of the hand modified by the friction
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),40
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)
EndFunction
Function Fingers()
If MouseClick()=0 Then ExitFunction
Dim Limbs(14)
up=(Mouseclick()=2)-(MouseClick()=1)
n=Check_Collision("limb",10,0,20,2,1)
For i=1 to 14
Limbs(i)=Check_Collision("limb",10,i,20,3,1)
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)*2,fa(i),0
Next i
Print n
Remstart
Rotate Limb 10,1,Limb Angle X(10,1)+KeyState(47)*up*(Limb Angle X(10,1)+up>0 and Limb Angle X(10,1)+up<80)*2,20-(1*5),0
Rotate Limb 10,2,Limb Angle X(10,2)+KeyState(33)*up*(Limb Angle X(10,2)+up>0 and Limb Angle X(10,2)+up<80)*2,0,0
Rotate Limb 10,3,Limb Angle X(10,3)+KeyState(19)*up*(Limb Angle X(10,3)+up>0 and Limb Angle X(10,3)+up<80)*2,0,0
Rotate Limb 10,4,Limb Angle X(10,4)+KeyState(46)*up*(Limb Angle X(10,4)+up>0 and Limb Angle X(10,4)+up<80)*2,20-(4*5),0
Rotate Limb 10,5,Limb Angle X(10,5)+KeyState(32)*up*(Limb Angle X(10,5)+up>0 and Limb Angle X(10,5)+up<80)*2,0,0
Rotate Limb 10,6,Limb Angle X(10,6)+KeyState(18)*up*(Limb Angle X(10,6)+up>0 and Limb Angle X(10,6)+up<80)*2,0,0
Rotate Limb 10,7,Limb Angle X(10,7)+KeyState(45)*up*(Limb Angle X(10,7)+up>0 and Limb Angle X(10,7)+up<80)*2,20-(7*5),0
Rotate Limb 10,8,Limb Angle X(10,8)+KeyState(31)*up*(Limb Angle X(10,8)+up>0 and Limb Angle X(10,8)+up<80)*2,0,0
Rotate Limb 10,9,Limb Angle X(10,9)+KeyState(17)*up*(Limb Angle X(10,9)+up>0 and Limb Angle X(10,9)+up<80)*2,0,0
Rotate Limb 10,10,Limb Angle X(10,10)+KeyState(44)*up*(Limb Angle X(10,10)+up>0 and Limb Angle X(10,10)+up<80)*2,20-(10*5),0
Rotate Limb 10,11,Limb Angle X(10,11)+KeyState(30)*up*(Limb Angle X(10,11)+up>0 and Limb Angle X(10,11)+up<80)*2,0,0
Rotate Limb 10,12,Limb Angle X(10,12)+KeyState(16)*up*(Limb Angle X(10,12)+up>0 and Limb Angle X(10,12)+up<80)*2,0,0
Rotate Limb 10,13,Limb Angle X(10,13)+KeyState(57)*up*(Limb Angle X(10,13)+up>0 and Limb Angle X(10,13)+up<80)*2,90,0
Rotate Limb 10,14,Limb Angle X(10,14)+KeyState(48)*up*(Limb Angle X(10,14)+up>0 and Limb Angle X(10,14)+up<80)*2,0,0
remend
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+5000000
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)
dim fpos(2) as Float
Local mesh as DWord
Select Lower$(type$)
Case "object"
Mesh=ObjectID+5000000
If Mesh Exist(ObjectID+5000000)=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)-1
accuracy#=accuracy#/100.0
n#=.01
fpos(0)=ox#*.01
fpos(1)=oy#*.01
fpos(2)=oz#*.01
st=1.0/accuracy#
For i = 0+cFlag to VIC+cFlag 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(0)=fpos(0)+(ox#+X Vector3(1))*id2#
fpos(1)=fpos(1)+(oy#+Y Vector3(1))*id2#
fpos(2)=fpos(2)+(oz#+Z Vector3(1))*id2#
n#=n#+id2#
Endif
next j
Next i
cFlag=cFlag+1
if cFlag>cycles then cFlag=0
fpos(0)=fpos(0)/n#
fpos(1)=fpos(1)/n#
fpos(2)=fpos(2)/n#
Unlock VertexData
Hit=(n#>.2)
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
"Droids don't rip your arms off when they lose." -H. Solo
REALITY II