Breakable joints
I cleaned up the code some, added comments.
Features dbodyGetForce, dbodyGetTorque, and timer based physics, mouse look, and rendering.
This should run at the same speed on most machines.
As always many ways to accomplish these things.
; ###################################################################################################
; # JV-ODE - BreakMe Ragdoll Demo #
; # Code by Jim Williams (VIP3R) #
; ###################################################################################################
AppTitle "JV-ODE - BreakMe Ragdoll Demo"
Include "JV-ODE.bb"
Graphics3D 800,600,0,2
Global RagDollMax=1
Dim Head(RagDollMax)
Dim BodyU(RagDollMax)
Dim BodyL(RagDollMax)
Dim LArmU(RagDollMax)
Dim LArmL(RagDollMax)
Dim RArmU(RagDollMax)
Dim RArmL(RagDollMax)
Dim LLegU(RagDollMax)
Dim LLegL(RagDollMax)
Dim RLegU(RagDollMax)
Dim RLegL(RagDollMax)
Dim LFoot(RagDollMax)
Dim RFoot(RagDollMax)
Dim RDJoint(RagDollMax,12)
Type ODEGeom
Field body
Field geom
Field mesh
Field mass
End Type
; ###################################################################################################
; ### Setup ODE
Global World=dWorldCreate()
Global Space=dHashSpaceCreate(0)
Global ContactGroup=dJointGroupCreate(0)
Global BigG#=-0.98
dWorldSetAutoDisableFlag(World,1)
dWorldSetGravity(World,0,BigG#,0)
dContactSetMode(dContactSlip1+dContactBounce)
dContactSetBounce(0.3)
dContactSetMu(48)
dWorldSetQuickStepNumIterations (World,20) ; default 20
; ### Create light
Global Light=CreateLight()
RotateEntity Light,45,-90,0
LightColor Light,255,255,255
AmbientLight 130,130,130
; ### Create camera
Global Camera=CreateCamera()
CameraZoom Camera,1.0
CameraClsColor Camera,0,0,0
CameraRange Camera,1,1000
PositionEntity Camera,20,20,-10
RotateEntity Camera,5,45,0
; ### Create plane
dCreatePlane(Space,0,1,0,0)
Plane=CreatePlane()
EntityAlpha Plane,0.8
PlaneTexture=CreateTexture(128,128,9)
ClsColor 0,150,80
Cls
Color 200,200,200
Rect 0,0,64,64,1
Rect 64,64,64,64,1
CopyRect 0,0,128,128,0,0,BackBuffer(),TextureBuffer(PlaneTexture)
ScaleTexture PlaneTexture,20,20
EntityTexture Plane,PlaneTexture,0,0
Color 255,255,255
Mirror=CreateMirror()
; ###################################################################################################
CreateRagDoll(count)
block.ODEGeom=New ODEGeom
x_pos#=-8
y_pos#=15
z_pos#=12
width#=2
length#=2
depth#=2
x_rot#=0
y_rot#=0
z_rot#=0
weight#=100.0
block\body=dBodyCreate(World)
block\mass=dMassCreate()
dMassSetBoxTotal(block\mass,weight, width, length, depth)
dBodySetMass(block\body,block\mass)
dBodySetPosition(block\body, x_pos, y_pos, z_pos)
dBodySetRotation(block\body, x_rot, y_rot, z_rot)
block\geom=dCreateBox(Space,width, length, depth)
dGeomSetBody(block\geom,block\body)
dGeomContactSetBounce(block\geom,0.5)
set_object_friction(block,0.5,weight)
dGeomContactSetMode(block\geom,dContactSlip1+dContactBounce)
block\mesh=CreateCube()
ScaleEntity block\mesh,width/2,length/2,depth/2
seesaw.ODEGeom=New ODEGeom
seesaw\mass=dMassCreate()
x_pos#=-8
y_pos#=5
z_pos#=8
width#=3
length#=0.5
depth#=15
x_rot#=-20
y_rot#=0
z_rot#=0
weight#=2.0
seesaw\body=dBodyCreate(World)
dMassSetBoxTotal(seesaw\mass,weight, width, length, depth)
dBodySetMass(seesaw\body,seesaw\mass)
dBodySetPosition(seesaw\body, x_pos, y_pos, z_pos)
seesaw\geom=dCreateBox(Space,width, length, depth)
dGeomSetBody(seesaw\geom,seesaw\body)
dGeomContactSetBounce(seesaw\geom,0.5)
set_object_friction(seesaw,0.5,weight)
dGeomContactSetMode(seesaw\geom,dContactSlip1+dContactBounce)
seesaw\mesh=CreateCube()
; Blitz box lengths 2x longer than ODE box length
ScaleEntity seesaw\mesh,width/2,length/2,depth/2
dBodyDisable(seesaw\body)
seesaw_joint=dJointCreateHinge(World,0)
dJointAttach(seesaw_joint, seesaw\body, 0)
dJointSetHingeAxis(seesaw_joint,1,0,0)
dJointSetHingeAnchor(seesaw_joint,-8,4,8)
dJointSetHingeParam(seesaw_joint,dParamLoStop,-dinfinity)
dJointSetHingeParam(seesaw_joint,dParamHiStop,dinfinity)
dBodySetRotation(seesaw\body, x_rot, y_rot, z_rot)
;===============================================================
; Render Loop
While Not KeyHit(1)
; Calculate Time
If T=0 Then T=MilliSecs()
T=MilliSecs()
;-----------------------------------------------------------
; Mouse Look code
; Poll Mouse Movement every 33ms ( 30/sec )
If T > Time2 + 33 Then
Time2=T
mxs#=mxs#+(MouseXSpeed()-mxs#)/3
mys#=mys#+(MouseYSpeed()-mys#)/3
If MouseDown(2) Then
MoveMouse GraphicsWidth()/2,GraphicsHeight()/2
p1#=p1#-mys#
y1#=y1#-mxs#
RotateEntity camera,-p1#,y1#,0
EndIf
EndIf
;----------------------------------------------------------
; WSAD - Movement
; W- Forward
If KeyDown(17) Or KeyDown(200) Then
MoveEntity camera,0,0,1
EndIf
; S- Reverse
If KeyDown(31) Or KeyDown(208) Then
MoveEntity camera,0,0,-1
EndIf
; A- Left
If KeyDown(30) Or KeyDown(203) Then
MoveEntity camera,-1,0,0
EndIf
; D- Right
If KeyDown(32) Or KeyDown(205) Then
MoveEntity camera,1,0,0
EndIf
;-----------------------------------------------
; Physics
;
; Run Physics every 10ms ( 100 Times/sec )
If T > Time3 + 10 Then
Time3=T
PTime=MilliSecs()
UpdateGeoms()
For x=1 To 2 ; Increase to speed up simulation
dSpaceCollide(Space,World,ContactGroup)
dWorldQuickStep(World,0.05)
updatefriction()
dJointGroupEmpty(ContactGroup)
Next
PhysicsTime#=MilliSecs()-PTime
End If
;-----------------------------------------------
; render world every 33ms ( 30 FPS )
If T > Time4 + 33 Then
Time4=T
RenderWorld
EndIf
;-----------------------------------------------
; Break joints for each body
rd=0 ; Ragdoll id
Jlimit#=250 ; Joint Limit, hand tuned, larger limit resists breakage.
JointLimits(Head(rd),Jlimit#)
JointLimits(BodyU(rd),Jlimit#)
JointLimits(BodyL(rd),Jlimit#)
JointLimits(LArmU(rd),Jlimit#)
JointLimits(LArmL(rd),Jlimit#)
JointLimits(RArmU(rd),Jlimit#)
JointLimits(RArmL(rd),Jlimit#)
JointLimits(LLegU(rd),Jlimit#)
JointLimits(LLegL(rd),Jlimit#)
JointLimits(RLegU(rd),Jlimit#)
JointLimits(RLegL(rd),Jlimit#)
JointLimits(LFoot(rd),Jlimit#)
JointLimits(RFoot(rd),Jlimit#)
Text 0,0,"Gravity="+Str(BigG#)
Text 0,15,"Adjust Gravity - Mouse wheel"
Text 0,30,"Reset - Space"
Text 0,45,"Physics Time:"+PhysicsTime
Flip
; Adjust Gravity - mouse wheel
BigG#=BigG#+(MouseZSpeed()/100.0)
dWorldSetGravity(World,0,BigG#,0)
;--------------------------------------------------------
; Space - Resets See Saw, Jumper, block and drops it.
If KeyHit(57)
; Position See Saw
x_pos#=-8
y_pos#=5
z_pos#=8
x_rot#=-20
y_rot#=0
z_rot#=0
dBodySetPosition(seesaw\body, x_pos, y_pos, z_pos)
dBodySetRotation(seesaw\body, x_rot, y_rot, z_rot)
dBodySetLinearVel(seesaw\body,0,0,0)
dBodySetAngularVel(seesaw\body,0,0,0)
dBodyDisable(seesaw\body)
xp=-8
yp=9
zp=2
; ### Position Head
dBodySetRotation(Head(rd),0,0,0)
dBodySetPosition(Head(rd),xp,yp,zp)
dBodySetAutoDisableFlag(Head(rd),1)
dBodySetLinearVel(Head(rd),0,0,0)
dBodySetAngularVel(Head(rd),0,0,0)
dBodySetForce(Head(rd),0,0,0)
dBodySetTorque(Head(rd),0,0,0)
dBodyDisable(Head(rd))
; ### Position Body (Upper)
dBodySetRotation(BodyU(rd),0,0,0)
dBodySetPosition(BodyU(rd),xp,yp-1.25,zp)
dBodySetAutoDisableFlag(BodyU(rd),1)
dBodySetLinearVel(BodyU(rd),0,0,0)
dBodySetAngularVel(BodyU(rd),0,0,0)
dBodySetForce(BodyU(rd),0,0,0)
dBodySetTorque(BodyU(rd),0,0,0)
dBodyDisable(BodyU(rd))
; ### Position Body (Lower)
dBodySetRotation(BodyL(rd),0,0,0)
dBodySetPosition(BodyL(rd),xp,yp-2.5,zp)
dBodySetAutoDisableFlag(BodyL(rd),1)
dBodySetLinearVel(BodyL(rd),0,0,0)
dBodySetAngularVel(BodyL(rd),0,0,0)
dBodySetForce(BodyL(rd),0,0,0)
dBodySetTorque(BodyL(rd),0,0,0)
dBodyDisable(BodyL(rd))
; ### Position Left Arm (Upper)
dBodySetRotation(LArmU(rd),90,0,0)
dBodySetPosition(LArmU(rd),xp+1,yp-1.25,zp)
dBodySetAutoDisableFlag(LArmU(rd),1)
dBodySetLinearVel(LArmU(rd),0,0,0)
dBodySetAngularVel(LArmU(rd),0,0,0)
dBodySetForce(LArmU(rd),0,0,0)
dBodySetTorque(LArmU(rd),0,0,0)
dBodyDisable(LArmU(rd))
; ### Position Left Arm (Lower)
dBodySetRotation(LArmL(rd),90,0,0)
dBodySetPosition(LArmL(rd),xp+1,yp-2.5,zp)
dBodySetAutoDisableFlag(LArmL(rd),1)
dBodySetLinearVel(LArmL(rd),0,0,0)
dBodySetAngularVel(LArmL(rd),0,0,0)
dBodySetForce(LArmL(rd),0,0,0)
dBodySetTorque(LArmL(rd),0,0,0)
dBodyDisable(LArmL(rd))
; ### Position Right Arm (Upper)
dBodySetRotation(RArmU(rd),90,0,0)
dBodySetPosition(RArmU(rd),xp-1,yp-1.25,zp)
dBodySetAutoDisableFlag(RArmU(rd),1)
dBodySetLinearVel(RArmU(rd),0,0,0)
dBodySetAngularVel(RArmU(rd),0,0,0)
dBodySetForce(RArmU(rd),0,0,0)
dBodySetTorque(RArmU(rd),0,0,0)
dBodyDisable(RArmU(rd))
; ### Position Right Arm (Lower)
dBodySetRotation(RArmL(rd),90,0,0)
dBodySetPosition(RArmL(rd),xp-1,yp-2.5,zp)
dBodySetAutoDisableFlag(RArmL(rd),1)
dBodySetLinearVel(RArmL(rd),0,0,0)
dBodySetAngularVel(RArmL(rd),0,0,0)
dBodySetForce(RArmL(rd),0,0,0)
dBodySetTorque(RArmL(rd),0,0,0)
dBodyDisable(RArmL(rd))
; ### Position Left Leg (Upper)
dBodySetRotation(LLegU(rd),90,0,0)
dBodySetPosition(LLegU(rd),xp+0.5,yp-3.6,zp)
dBodySetAutoDisableFlag(LLegU(rd),1)
dBodySetLinearVel(LLegU(rd),0,0,0)
dBodySetAngularVel(LLegU(rd),0,0,0)
dBodySetForce(LLegU(rd),0,0,0)
dBodySetTorque(LLegU(rd),0,0,0)
dBodyDisable(LLegU(rd))
; ### Position Left Leg (Lower)
dBodySetRotation(LLegL(rd),90,0,0)
dBodySetPosition(LLegL(rd),xp+0.5,yp-4.9,zp)
dBodySetAutoDisableFlag(LLegL(rd),1)
dBodySetLinearVel(LLegL(rd),0,0,0)
dBodySetAngularVel(LLegL(rd),0,0,0)
dBodySetForce(LLegL(rd),0,0,0)
dBodySetTorque(LLegL(rd),0,0,0)
dBodyDisable(LLegL(rd))
; ### Position Right Leg (Upper)
dBodySetRotation(RLegU(rd),90,0,0)
dBodySetPosition(RLegU(rd),xp-0.5,yp-3.6,zp)
dBodySetAutoDisableFlag(RLegU(rd),1)
dBodySetLinearVel(RLegU(rd),0,0,0)
dBodySetAngularVel(RLegU(rd),0,0,0)
dBodySetForce(RLegU(rd),0,0,0)
dBodySetTorque(RLegU(rd),0,0,0)
dBodyDisable(RLegU(rd))
; ### Position Right Leg (Lower)
dBodySetRotation(RLegL(rd),90,0,0)
dBodySetPosition(RLegL(rd),xp-0.5,yp-4.9,zp)
dBodySetAutoDisableFlag(RLegL(rd),1)
dBodySetLinearVel(RLegL(rd),0,0,0)
dBodySetAngularVel(RLegL(rd),0,0,0)
dBodySetForce(RLegL(rd),0,0,0)
dBodySetTorque(RLegL(rd),0,0,0)
dBodyDisable(RLegL(rd))
; ### Position Left Foot
dBodySetRotation(LFoot(rd),0,0,0)
dBodySetPosition(LFoot(rd),xp+0.5,yp-5.7,zp-0.25)
dBodySetAutoDisableFlag(LFoot(rd),1)
dBodySetLinearVel(LFoot(rd),0,0,0)
dBodySetAngularVel(LFoot(rd),0,0,0)
dBodySetForce(LFoot(rd),0,0,0)
dBodySetTorque(LFoot(rd),0,0,0)
dBodyDisable(LFoot(rd))
; ### Position Right Foot
dBodySetRotation(RFoot(rd),0,0,0)
dBodySetPosition(RFoot(rd),xp-0.5,yp-5.7,zp-0.25)
dBodySetAutoDisableFlag(RFoot(rd),1)
dBodySetLinearVel(RFoot(rd),0,0,0)
dBodySetAngularVel(RFoot(rd),0,0,0)
dBodySetForce(RFoot(rd),0,0,0)
dBodySetTorque(RFoot(rd),0,0,0)
dBodyDisable(RFoot(rd))
x_pos#=-8
y_pos#=15
z_pos#=12
x_rot#=0
y_rot#=0
z_rot#=0
dBodySetPosition(block\body, x_pos, y_pos, z_pos)
dBodySetRotation(block\body, x_rot, y_rot, z_rot)
dBodySetLinearVel(block\body,0,0,0)
dBodySetAngularVel(block\body,0,0,0)
dBodyEnable(block\body)
; Reconnect joints (in case we broke them)
dJointAttach(RDJoint(rd,1),Head(rd),BodyU(rd))
dJointAttach(RDJoint(rd,2),BodyU(rd),BodyL(rd))
dJointAttach(RDJoint(rd,3),LArmU(rd),BodyU(rd))
dJointAttach(RDJoint(rd,4),LArmL(rd),LArmU(rd))
dJointAttach(RDJoint(rd,5),RArmU(rd),BodyU(rd))
dJointAttach(RDJoint(rd,6),RArmL(rd),RArmU(rd))
dJointAttach(RDJoint(rd,7),LLegU(rd),BodyL(rd))
dJointAttach(RDJoint(rd,8),LLegL(rd),LLegU(rd))
dJointAttach(RDJoint(rd,9),RLegU(rd),BodyL(rd))
dJointAttach(RDJoint(rd,10),RLegL(rd),RLegU(rd))
dJointAttach(RDJoint(rd,11),LFoot(rd),LLegL(rd))
dJointAttach(RDJoint(rd,12),RFoot(rd),RLegL(rd))
End If
Wend
dJointGroupDestroy(ContactGroup)
dSpaceDestroy(Space)
dWorldDestroy(World)
dCloseODE()
End
; ###################################################################################################
Function CreateRagDoll(rd)
xp=-8
yp=9
zp=2
; ### RagDoll Dimensions
headrad#=0.4
bodytx#=1.5
bodyty#=1.5
bodytz#=0.5
bodybx#=1.5
bodyby#=0.75
bodybz#=0.5
larmrad#=0.15
larmlen#=0.9
rarmrad#=0.15
rarmlen#=0.9
llegrad#=0.25
lleglen#=0.8
rlegrad#=0.25
rleglen#=0.8
feetx#=0.5
feety#=0.25
feetz#=1.0
weight#=1.0
; ### Create Head
ode.ODEGeom=New ODEGeom
ode\body=dBodyCreate(World)
Head(rd)=ode\body
dBodySetRotation(ode\body,0,0,0)
dBodySetPosition(ode\body,xp,yp,zp)
dBodySetAutoDisableFlag(ode\body,1)
ode\mass=dMassCreate()
dMassSetBoxTotal(ode\mass,weight, width, length, depth)
dBodySetMass(ode\body,ode\mass)
ode\geom=dCreateSphere(Space,headrad)
dGeomSetBody(ode\geom,ode\body)
ode\mesh=CreateSphere()
EntityPickMode ode\mesh,2
ScaleMesh ode\mesh,headrad,headrad,headrad
EntityColor ode\mesh,255,255,255
dBodyDisable(ode\body)
; ### Create Body (Upper)
ode.ODEGeom=New ODEGeom
ode\body=dBodyCreate(World)
BodyU(rd)=ode\body
dBodySetRotation(ode\body,0,0,0)
dBodySetPosition(ode\body,xp,yp-1.25,zp)
dBodySetAutoDisableFlag(ode\body,1)
ode\mass=dMassCreate()
dMassSetBoxTotal(ode\mass,weight, width, length, depth)
dBodySetMass(ode\body,ode\mass)
ode\geom=dCreateBox(Space,bodytx,bodyty,bodytz)
dGeomSetBody(ode\geom,ode\body)
ode\mesh=CreateCube()
EntityPickMode ode\mesh,2
ScaleMesh ode\mesh,bodytx*0.5,bodyty*0.5,bodytz*0.5
EntityColor ode\mesh,0,200,200
dBodyDisable(ode\body)
; ### Create Body (Lower)
ode.ODEGeom=New ODEGeom
ode\body=dBodyCreate(World)
BodyL(rd)=ode\body
dBodySetRotation(ode\body,0,0,0)
dBodySetPosition(ode\body,xp,yp-2.5,zp)
dBodySetAutoDisableFlag(ode\body,1)
ode\mass=dMassCreate()
dMassSetBoxTotal(ode\mass,weight, width, length, depth)
dBodySetMass(ode\body,ode\mass)
ode\geom=dCreateBox(Space,bodybx,bodyby,bodybz)
dGeomSetBody(ode\geom,ode\body)
ode\mesh=CreateCube()
EntityPickMode ode\mesh,2
ScaleMesh ode\mesh,bodybx*0.5,bodyby*0.5,bodybz*0.5
EntityColor ode\mesh,0,100,100
dBodyDisable(ode\body)
; ### Create Left Arm (Upper)
ode.ODEGeom=New ODEGeom
ode\body=dBodyCreate(World)
LArmU(rd)=ode\body
dBodySetRotation(ode\body,90,0,0)
dBodySetPosition(ode\body,xp+1,yp-1.25,zp)
dBodySetAutoDisableFlag(ode\body,1)
ode\mass=dMassCreate()
dMassSetBoxTotal(ode\mass,weight, width, length, depth)
dBodySetMass(ode\body,ode\mass)
ode\geom=dCreateCCylinder(Space,larmrad,larmlen)
dGeomSetBody(ode\geom,ode\body)
ode\mesh=CreateCylinder(8)
EntityPickMode ode\mesh,2
ScaleMesh ode\mesh,larmrad,(larmlen*0.5)+larmrad,larmrad
RotateMesh ode\mesh,90,0,0
EntityColor ode\mesh,255,0,0
dBodyDisable(ode\body)
; ### Create Left Arm (Lower)
ode.ODEGeom=New ODEGeom
ode\body=dBodyCreate(World)
LArmL(rd)=ode\body
dBodySetRotation(ode\body,90,0,0)
dBodySetPosition(ode\body,xp+1,yp-2.5,zp)
dBodySetAutoDisableFlag(ode\body,1)
ode\mass=dMassCreate()
dMassSetBoxTotal(ode\mass,weight, width, length, depth)
dBodySetMass(ode\body,ode\mass)
ode\geom=dCreateCCylinder(Space,larmrad,larmlen)
dGeomSetBody(ode\geom,ode\body)
ode\mesh=CreateCylinder(8)
EntityPickMode ode\mesh,2
ScaleMesh ode\mesh,larmrad,(larmlen*0.5)+larmrad,larmrad
RotateMesh ode\mesh,90,0,0
EntityColor ode\mesh,125,0,0
dBodyDisable(ode\body)
; ### Create Right Arm (Upper)
ode.ODEGeom=New ODEGeom
ode\body=dBodyCreate(World)
RArmU(rd)=ode\body
dBodySetRotation(ode\body,90,0,0)
dBodySetPosition(ode\body,xp-1,yp-1.25,zp)
dBodySetAutoDisableFlag(ode\body,1)
ode\mass=dMassCreate()
dMassSetBoxTotal(ode\mass,weight, width, length, depth)
dBodySetMass(ode\body,ode\mass)
ode\geom=dCreateCCylinder(Space,rarmrad,rarmlen)
dGeomSetBody(ode\geom,ode\body)
ode\mesh=CreateCylinder(8)
EntityPickMode ode\mesh,2
ScaleMesh ode\mesh,rarmrad,(rarmlen*0.5)+rarmrad,rarmrad
RotateMesh ode\mesh,90,0,0
EntityColor ode\mesh,0,255,0
dBodyDisable(ode\body)
; ### Create Right Arm (Lower)
ode.ODEGeom=New ODEGeom
ode\body=dBodyCreate(World)
RArmL(rd)=ode\body
dBodySetRotation(ode\body,90,0,0)
dBodySetPosition(ode\body,xp-1,yp-2.5,zp)
dBodySetAutoDisableFlag(ode\body,1)
ode\mass=dMassCreate()
dMassSetBoxTotal(ode\mass,weight, width, length, depth)
dBodySetMass(ode\body,ode\mass)
ode\geom=dCreateCCylinder(Space,rarmrad,rarmlen)
dGeomSetBody(ode\geom,ode\body)
ode\mesh=CreateCylinder(8)
EntityPickMode ode\mesh,2
ScaleMesh ode\mesh,rarmrad,(rarmlen*0.5)+rarmrad,rarmrad
RotateMesh ode\mesh,90,0,0
EntityColor ode\mesh,0,125,0
dBodyDisable(ode\body)
; ### Create Left Leg (Upper)
ode.ODEGeom=New ODEGeom
ode\body=dBodyCreate(World)
LLegU(rd)=ode\body
dBodySetRotation(ode\body,90,0,0)
dBodySetPosition(ode\body,xp+0.5,yp-3.6,zp)
dBodySetAutoDisableFlag(ode\body,1)
ode\mass=dMassCreate()
dMassSetBoxTotal(ode\mass,weight, width, length, depth)
dBodySetMass(ode\body,ode\mass)
ode\geom=dCreateCCylinder(Space,llegrad,lleglen)
dGeomSetBody(ode\geom,ode\body)
ode\mesh=CreateCylinder(8)
EntityPickMode ode\mesh,2
ScaleMesh ode\mesh,llegrad,(lleglen*0.5)+llegrad,llegrad
RotateMesh ode\mesh,90,0,0
EntityColor ode\mesh,255,0,0
dBodyDisable(ode\body)
; ### Create Left Leg (Lower)
ode.ODEGeom=New ODEGeom
ode\body=dBodyCreate(World)
LLegL(rd)=ode\body
dBodySetRotation(ode\body,90,0,0)
dBodySetPosition(ode\body,xp+0.5,yp-4.9,zp)
dBodySetAutoDisableFlag(ode\body,1)
ode\mass=dMassCreate()
dMassSetBoxTotal(ode\mass,weight, width, length, depth)
dBodySetMass(ode\body,ode\mass)
ode\geom=dCreateCCylinder(Space,llegrad,lleglen)
dGeomSetBody(ode\geom,ode\body)
ode\mesh=CreateCylinder(8)
EntityPickMode ode\mesh,2
ScaleMesh ode\mesh,llegrad,(lleglen*0.5)+llegrad,llegrad
RotateMesh ode\mesh,90,0,0
EntityColor ode\mesh,125,0,0
dBodyDisable(ode\body)
; ### Create Right Leg (Upper)
ode.ODEGeom=New ODEGeom
ode\body=dBodyCreate(World)
RLegU(rd)=ode\body
dBodySetRotation(ode\body,90,0,0)
dBodySetPosition(ode\body,xp-0.5,yp-3.6,zp)
dBodySetAutoDisableFlag(ode\body,1)
ode\mass=dMassCreate()
dMassSetBoxTotal(ode\mass,weight, width, length, depth)
dBodySetMass(ode\body,ode\mass)
ode\geom=dCreateCCylinder(Space,rlegrad,rleglen)
dGeomSetBody(ode\geom,ode\body)
ode\mesh=CreateCylinder(8)
EntityPickMode ode\mesh,2
ScaleMesh ode\mesh,rlegrad,(rleglen*0.5)+rlegrad,rlegrad
RotateMesh ode\mesh,90,0,0
EntityColor ode\mesh,0,255,0
dBodyDisable(ode\body)
; ### Create Right Leg (Lower)
ode.ODEGeom=New ODEGeom
ode\body=dBodyCreate(World)
RLegL(rd)=ode\body
dBodySetRotation(ode\body,90,0,0)
dBodySetPosition(ode\body,xp-0.5,yp-4.9,zp)
dBodySetAutoDisableFlag(ode\body,1)
ode\mass=dMassCreate()
dMassSetBoxTotal(ode\mass,weight, width, length, depth)
dBodySetMass(ode\body,ode\mass)
ode\geom=dCreateCCylinder(Space,rlegrad,rleglen)
dGeomSetBody(ode\geom,ode\body)
ode\mesh=CreateCylinder(8)
EntityPickMode ode\mesh,2
ScaleMesh ode\mesh,rlegrad,(rleglen*0.5)+rlegrad,rlegrad
RotateMesh ode\mesh,90,0,0
EntityColor ode\mesh,0,125,0
dBodyDisable(ode\body)
; ### Create Left Foot
ode.ODEGeom=New ODEGeom
ode\body=dBodyCreate(World)
LFoot(rd)=ode\body
dBodySetRotation(ode\body,0,0,0)
dBodySetPosition(ode\body,xp+0.5,yp-5.7,zp-0.25)
dBodySetAutoDisableFlag(ode\body,1)
ode\mass=dMassCreate()
dMassSetBoxTotal(ode\mass,weight, width, length, depth)
dBodySetMass(ode\body,ode\mass)
ode\geom=dCreateBox(Space,feetx,feety,feetz)
dGeomSetBody(ode\geom,ode\body)
ode\mesh=CreateCube()
EntityPickMode ode\mesh,2
ScaleMesh ode\mesh,feetx*0.5,feety*0.5,feetz*0.5
EntityColor ode\mesh,200,0,100
dBodyDisable(ode\body)
; ### Create Right Foot
ode.ODEGeom=New ODEGeom
ode\body=dBodyCreate(World)
RFoot(rd)=ode\body
dBodySetRotation(ode\body,0,0,0)
dBodySetPosition(ode\body,xp-0.5,yp-5.7,zp-0.25)
dBodySetAutoDisableFlag(ode\body,1)
ode\mass=dMassCreate()
dMassSetBoxTotal(ode\mass,weight, width, length, depth)
dBodySetMass(ode\body,ode\mass)
ode\geom=dCreateBox(Space,feetx,feety,feetz)
dGeomSetBody(ode\geom,ode\body)
ode\mesh=CreateCube()
EntityPickMode ode\mesh,2
ScaleMesh ode\mesh,feetx*0.5,feety*0.5,feetz*0.5
EntityColor ode\mesh,100,200,0
dBodyDisable(ode\body)
; ### Static Joint To Head
;RDJoint(rd,0)=dJointCreateBall(World,0)
;dJointAttach(RDJoint(rd,0),0,Head(rd))
;dJointSetBallAnchor(RDJoint(rd,0),xp,yp,zp)
; ### Head To Body (Upper)
RDJoint(rd,1)=dJointCreateHinge(World,0)
dJointAttach(RDJoint(rd,1),Head(rd),BodyU(rd))
dJointSetHingeAxis(RDJoint(rd,1),1,0,0)
dJointSetHingeAnchor(RDJoint(rd,1),xp,yp-0.25,zp)
dJointSetHingeParam(RDJoint(rd,1),dParamLoStop,-0.5)
dJointSetHingeParam(RDJoint(rd,1),dParamHiStop,0.5)
; ### Body (Upper) To Body (Lower)
RDJoint(rd,2)=dJointCreateHinge(World,0)
dJointAttach(RDJoint(rd,2),BodyU(rd),BodyL(rd))
dJointSetHingeAxis(RDJoint(rd,2),1,0,0)
dJointSetHingeAnchor(RDJoint(rd,2),xp,yp-2,zp)
dJointSetHingeParam(RDJoint(rd,2),dParamLoStop,-0.25)
dJointSetHingeParam(RDJoint(rd,2),dParamHiStop,0.25)
; ### Left Arm (Upper) To Body (Upper)
RDJoint(rd,3)=dJointCreateHinge(World,0)
dJointAttach(RDJoint(rd,3),LArmU(rd),BodyU(rd))
dJointSetHingeAxis(RDJoint(rd,3),1,-1,0)
dJointSetHingeAnchor(RDJoint(rd,3),xp+1,yp-0.75,zp)
dJointSetHingeParam(RDJoint(rd,3),dParamLoStop,-2.0)
dJointSetHingeParam(RDJoint(rd,3),dParamHiStop,2.0)
; ### Left Arm (Lower) To Left Arm (Upper)
RDJoint(rd,4)=dJointCreateHinge(World,0)
dJointAttach(RDJoint(rd,4),LArmL(rd),LArmU(rd))
dJointSetHingeAxis(RDJoint(rd,4),1,0,0)
dJointSetHingeAnchor(RDJoint(rd,4),xp+1,yp-2,zp)
dJointSetHingeParam(RDJoint(rd,4),dParamLoStop,0.0)
dJointSetHingeParam(RDJoint(rd,4),dParamHiStop,2.0)
; ### Right Arm (Upper) To Body (Upper)
RDJoint(rd,5)=dJointCreateHinge(World,0)
dJointAttach(RDJoint(rd,5),RArmU(rd),BodyU(rd))
dJointSetHingeAxis(RDJoint(rd,5),1,1,0)
dJointSetHingeAnchor(RDJoint(rd,5),xp-1,yp-0.75,zp)
dJointSetHingeParam(RDJoint(rd,5),dParamLoStop,-2.0)
dJointSetHingeParam(RDJoint(rd,5),dParamHiStop,2.0)
; ### Right Arm (Lower) To Right Arm (Upper)
RDJoint(rd,6)=dJointCreateHinge(World,0)
dJointAttach(RDJoint(rd,6),RArmL(rd),RArmU(rd))
dJointSetHingeAxis(RDJoint(rd,6),1,0,0)
dJointSetHingeAnchor(RDJoint(rd,6),xp-1,yp-2,zp)
dJointSetHingeParam(RDJoint(rd,6),dParamLoStop,0.0)
dJointSetHingeParam(RDJoint(rd,6),dParamHiStop,2.0)
; ### Left Leg (Upper) To Body (Lower)
RDJoint(rd,7)=dJointCreateHinge(World,0)
dJointAttach(RDJoint(rd,7),LLegU(rd),BodyL(rd))
dJointSetHingeAxis(RDJoint(rd,7),1,0,0)
dJointSetHingeAnchor(RDJoint(rd,7),xp+1,yp-2.75,zp)
dJointSetHingeParam(RDJoint(rd,7),dParamLoStop,-1.0)
dJointSetHingeParam(RDJoint(rd,7),dParamHiStop,1.0)
; ### Left Leg (Lower) To Left Leg (Upper)
RDJoint(rd,8)=dJointCreateHinge(World,0)
dJointAttach(RDJoint(rd,8),LLegL(rd),LLegU(rd))
dJointSetHingeAxis(RDJoint(rd,8),1,0,0)
dJointSetHingeAnchor(RDJoint(rd,8),xp+1,yp-4.25,zp)
dJointSetHingeParam(RDJoint(rd,8),dParamLoStop,-2.0)
dJointSetHingeParam(RDJoint(rd,8),dParamHiStop,0.0)
; ### Right Leg (Upper) To Body (Lower)
RDJoint(rd,9)=dJointCreateHinge(World,0)
dJointAttach(RDJoint(rd,9),RLegU(rd),BodyL(rd))
dJointSetHingeAxis(RDJoint(rd,9),1,0,0)
dJointSetHingeAnchor(RDJoint(rd,9),xp-1,yp-2.75,zp)
dJointSetHingeParam(RDJoint(rd,9),dParamLoStop,-1.0)
dJointSetHingeParam(RDJoint(rd,9),dParamHiStop,1.0)
; ### Right Leg (Lower) To Right Leg (Upper)
RDJoint(rd,10)=dJointCreateHinge(World,0)
dJointAttach(RDJoint(rd,10),RLegL(rd),RLegU(rd))
dJointSetHingeAxis(RDJoint(rd,10),1,0,0)
dJointSetHingeAnchor(RDJoint(rd,10),xp-1,yp-4.25,zp)
dJointSetHingeParam(RDJoint(rd,10),dParamLoStop,-2.0)
dJointSetHingeParam(RDJoint(rd,10),dParamHiStop,0.0)
; ### Left Foot To Left Leg (Lower)
RDJoint(rd,11)=dJointCreateHinge(World,0)
dJointAttach(RDJoint(rd,11),LFoot(rd),LLegL(rd))
dJointSetHingeAxis(RDJoint(rd,11),1,0,0)
dJointSetHingeAnchor(RDJoint(rd,11),xp+1,yp-5.5,zp)
dJointSetHingeParam(RDJoint(rd,11),dParamLoStop,-0.25)
dJointSetHingeParam(RDJoint(rd,11),dParamHiStop,0.25)
; ### Right Foot To Right Leg (Lower)
RDJoint(rd,12)=dJointCreateHinge(World,0)
dJointAttach(RDJoint(rd,12),RFoot(rd),RLegL(rd))
dJointSetHingeAxis(RDJoint(rd,12),1,0,0)
dJointSetHingeAnchor(RDJoint(rd,12),xp-1,yp-5.5,zp)
dJointSetHingeParam(RDJoint(rd,12),dParamLoStop,-0.25)
dJointSetHingeParam(RDJoint(rd,12),dParamHiStop,0.25)
End Function
Function UpdateGeoms()
For ode.ODEGeom=Each ODEGeom
; If dBodyIsEnabled(ode\body)
RotateEntity ode\mesh,dGeomGetPitch#(ode\geom),dGeomGetYaw#(ode\geom),dGeomGetRoll#(ode\geom)
PositionEntity ode\mesh,dGeomGetPositionX#(ode\geom),dGeomGetPositionY#(ode\geom),dGeomGetPositionZ#(ode\geom)
; End If
Next
End Function
; ###################################################################################################
Function set_object_friction(obj.ODEGeom,friction#,weight)
friction=friction/100
friction=friction
friction=friction*4
friction=4-friction
e#=Log10(weight*10)
e=e-friction
e=1*(10^e)
dGeomContactSetMu(obj\geom,e)
End Function
; ###################################################################################################
Function LinearDamp(body,damp#)
dBodyAddForce body,dBodyGetLinearVelX(body)*-damp,dBodyGetLinearVelY(body)*-damp,dBodyGetLinearVelZ(body)*-damp
End Function
; ###################################################################################################
Function AngularDamp(body,damp#)
dBodyAddTorque body,dBodyGetAngularVelX(body)*-damp,dBodyGetAngularVelY(body)*-damp,dBodyGetAngularVelZ(body)*-damp
End Function
; ###################################################################################################
Function JointLimits(body,limit#)
For ode.ODEGeom=Each ODEGeom
If dGeomIsEnabled(ode\geom)
If body=ode\body ; specific body parts only
numjoints=dBodyGetNumJoints(ode\body)
If numjoints>0
For joints=0 To numjoints-1
joint=dBodyGetJoint(ode\body,joints)
If joint<>0 ; valid joints only
If dJointGetType(joint)<>dJointTypeContact
; Get Force vector
dBodyGetForce(joint)
fx#=dVectorX()
fy#=dVectorY()
fz#=dVectorZ()
; Calculate magnitude
ForceF#=Sqr(fx*fx+fy*fy+fz*fz)
; Get Torque vector
dBodyGetTorque(joint)
fx#=dVectorX()
fy#=dVectorY()
fz#=dVectorZ()
; Calculate magnitude
ForceT#=Sqr(fx*fx+fy*fy+fz*fz)
; Check to see if joint limit exceeded
If Abs(ForceF#)>limit Or Abs(ForceT#)>limit Then
dJointAttach(joint,0,0)
; Reduce body part energy due to break
If ForceA>.01
LinearDamp(ode\body,.04)
End If
If ForceB>.01
AngularDamp(ode\body,.04)
End If
End If
End If
End If
Next
End If
End If
End If
Next
End Function
; ###################################################################################################
Function UpdateFriction()
For ode.ODEGeom=Each ODEGeom
; add friction force if body enabled
If dBodyIsEnabled(ode\body) And ode\body<>Car
numjoints=dBodyGetNumJoints(ode\body)
If numjoints>0
;DebugLog "joints=" + Str(joints)
For joints=0 To numjoints-1
joint1=dBodyGetJoint(ode\body,joints)
If dJointGetType(joint1)=dJointTypeContact
; Get linear velocity vector
ax#=dBodyGetLinearVelX#(ode\body)
ay#=dBodyGetLinearVelY#(ode\body)
az#=dBodyGetLinearVelZ#(ode\body)
; Get Angular velocity vector
bx#=dBodyGetAngularVelX#(ode\body)
by#=dBodyGetAngularVelY#(ode\body)
bz#=dBodyGetAngularVelZ#(ode\body)
; Calculate magnitudes
ForceA#=Sqr(ax*ax+ay*ay+az*az)
ForceB#=Sqr(bx*bx+by*by+bz*bz)
If ForceA>.01
LinearDamp(ode\body,.04)
End If
If ForceB>.01
AngularDamp(ode\body,.04)
End If
End If
Next
End If
End If
Next
End Function