; ################################################################################################### ; # JV-ODE - Ragdoll Demo # ; # Code by Jim Williams (VIP3R) # ; ################################################################################################### AppTitle "JV-ODE - Ragdoll Demo" Include "JV-ODE.bb" Graphics3D 800,600,0,2 Global RagDollMax=3 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 End Type ; ################################################################################################### ; ### Setup ODE Global World=dWorldCreate() Global Space=dHashSpaceCreate(0) Global ContactGroup=dJointGroupCreate(0) dWorldSetAutoDisableFlag(World,1) dWorldSetGravity(World,0,-0.98,0) dContactSetMode(dContactSlip1+dContactBounce) dContactSetBounce(0.0) dSetInternalContactSurfaceMode(1) ; ### Create light Global Light=CreateLight() RotateEntity Light,45,-90,0 LightColor Light,255,255,255 AmbientLight 130,130,130 ; ### Create camera Global Camera=CreateCamera() CameraClsColor Camera,0,0,0 CameraRange Camera,1,1000 PositionEntity Camera,0,20,-50 RotateEntity Camera,20,0,0 CameraZoom Camera,2 ; ### 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) ; ### Box cube.ODEGeom=New ODEGeom cube\geom=dCreateBox(Space,10,2,10) dGeomSetPosition(cube\geom,0,1,0) dGeomContactSetBounce(cube\geom,0.80) dGeomContactSetMu(cube\geom,100) cube\mesh=CreateCube() EntityPickMode cube\mesh,2 ScaleMesh cube\mesh,5,1,5 PositionEntity cube\mesh,0,1,0 EntityColor cube\mesh,250,210,0 dBodySetTorque(BodyU(0),50,0,0) box.ODEGeom=New ODEGeom box\body=dBodyCreate(World) dBodySetRotation(box\body,0,0,0) dBodySetPosition(box\body,-4,20,0) dBodySetAutoDisableFlag(box\body,1) box\geom=dCreateBox(Space,2,2,2) dGeomSetBody(box\geom,box\body) box\mesh=CreateCube() EntityPickMode box\mesh,2 ScaleMesh box\mesh,1,1,1 dBodySetTorque(box\body,0,0,0) While Not KeyHit(1) UpdateControls() PTime=MilliSecs() UpdateGeoms() dSpaceCollide(Space,World,ContactGroup) dWorldQuickStep(World,0.1) dJointGroupEmpty(ContactGroup) PhysicsTime#=MilliSecs()-PTime UpdateWorld RenderWorld Text 0,0,"JV-ODE Version "+dGetVersion() Text 0,15,"Physics Time:"+PhysicsTime Text 300,0,"F1 - Drop RagDoll 1" Text 300,15,"F2 - Drop RagDoll 2" Text 300,30,"F3 - Drop RagDoll 3" Text 300,50,"Space - Throw RagDolls" Text 300,65,"Arrow Keys - Move Camera" Text 580,0,"F4 - Attach RagDoll 1" Text 580,15,"F5 - Attach RagDoll 2" Text 580,30,"F6 - Attach RagDoll 3" Text 580,50,"L Mouse Button - Push Body" Text 580,65,"R Mouse Button - Pull Body" Flip Wend dJointGroupDestroy(ContactGroup) dSpaceDestroy(Space) dWorldDestroy(World) dCloseODE() End ; ################################################################################################### Function CreateRagDoll(rd) xp=0 yp=20 zp=0 ; ### 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 ; ### 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\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 ; ### 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\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 ; ### 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\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 ; ### 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\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 ; ### 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\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 ; ### 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\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 ; ### 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\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 ; ### 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\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 ; ### 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\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 ; ### 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\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 ; ### 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\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 ; ### 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\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 ; ### 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\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 ; ***** JOINTS JOINTS JOINTS ***** ; ### 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) dJointSetHingeParam(RDJoint(rd,1),dParamBounce,0.0) ; ### 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) dJointSetHingeParam(RDJoint(rd,2),dParamBounce,0.0) ; ### Left Arm (Upper) To Body (Upper) RDJoint(rd,3)=dJointCreateUniversal(World,0) dJointAttach(RDJoint(rd,3),LArmU(rd),BodyU(rd)) dJointSetUniversalAxis1(RDJoint(rd,3),1,0,0) dJointSetUniversalAxis2(RDJoint(rd,3),0,0,1) dJointSetUniversalAnchor(RDJoint(rd,3),xp+1,yp-0.75,zp) dJointSetUniversalParam(RDJoint(rd,3),dParamLoStop,-1.141) dJointSetUniversalParam(RDJoint(rd,3),dParamHiStop,1.141) dJointSetUniversalParam(RDJoint(rd,3),dParamLoStop2,0.0) dJointSetUniversalParam(RDJoint(rd,3),dParamHiStop2,3.000) ; ### 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)=dJointCreateUniversal(World,0) dJointAttach(RDJoint(rd,5),RArmU(rd),BodyU(rd)) dJointSetUniversalAxis1(RDJoint(rd,5),1,0,0) dJointSetUniversalAxis2(RDJoint(rd,5),0,0,-1) dJointSetUniversalAnchor(RDJoint(rd,5),xp-1,yp-0.75,zp) dJointSetUniversalParam(RDJoint(rd,5),dParamLoStop,-1.141) dJointSetUniversalParam(RDJoint(rd,5),dParamHiStop,1.141) dJointSetUniversalParam(RDJoint(rd,5),dParamLoStop2,0.0) dJointSetUniversalParam(RDJoint(rd,5),dParamHiStop2,3.000) ; ### 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)=dJointCreateUniversal(World,0) dJointAttach(RDJoint(rd,7),LLegU(rd),BodyL(rd)) dJointSetUniversalAxis1(RDJoint(rd,7),1,0,0) dJointSetUniversalAxis2(RDJoint(rd,7),0,0,1) dJointSetUniversalAnchor(RDJoint(rd,7),xp+0.7,yp-2.5,zp) dJointSetUniversalParam(RDJoint(rd,7),dParamLoStop,-1.0) dJointSetUniversalParam(RDJoint(rd,7),dParamHiStop,1.0) dJointSetUniversalParam(RDJoint(rd,7),dParamLoStop2,-0.0) dJointSetUniversalParam(RDJoint(rd,7),dParamHiStop2,1.500) ; ### 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)=dJointCreateUniversal(World,0) dJointAttach(RDJoint(rd,9),RLegU(rd),BodyL(rd)) dJointSetUniversalAxis1(RDJoint(rd,9),1,0,0) dJointSetUniversalAxis2(RDJoint(rd,9),0,0,1) dJointSetUniversalAnchor(RDJoint(rd,9),xp-0.7,yp-2.75,zp) dJointSetUniversalParam(RDJoint(rd,9),dParamLoStop,-1.0) dJointSetUniversalParam(RDJoint(rd,9),dParamHiStop,1.0) dJointSetUniversalParam(RDJoint(rd,9),dParamLoStop2,-0.0) dJointSetUniversalParam(RDJoint(rd,9),dParamHiStop2,1.500) ; ### 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 UpdateControls() If KeyDown(59)=1 Then dJointAttach(RDJoint(1,0),0,0) If KeyDown(60)=1 Then dJointAttach(RDJoint(2,0),0,0) If KeyDown(61)=1 Then dJointAttach(RDJoint(3,0),0,0) If KeyDown(62)=1 Then dJointAttach(RDJoint(1,0),0,Head(1)) If KeyDown(63)=1 Then dJointAttach(RDJoint(2,0),0,Head(2)) If KeyDown(64)=1 Then dJointAttach(RDJoint(3,0),0,Head(3)) If KeyDown(57)=1 ; dBodyAddForce Head(1),0,20,0 ; dBodyAddForce Head(2),0,20,0 ; dBodyAddForce Head(3),0,20,0 dJointSetBallAnchor(RDJoint(1,0),40,100,10) ; dBodySetPosition (Head(1),dBodyGetPositionX(Head(1))+1,dBodyGetPositionY(Head(1))+1, dBodyGetPositionZ(Head(1))+1) End If If KeyDown(200)=1 Then PositionEntity Camera,EntityX(Camera),EntityY(Camera),EntityZ(Camera)+0.3 If KeyDown(208)=1 Then PositionEntity Camera,EntityX(Camera),EntityY(Camera),EntityZ(Camera)-0.3 If KeyDown(203)=1 Then PositionEntity Camera,EntityX(Camera)-0.3,EntityY(Camera),EntityZ(Camera) If KeyDown(205)=1 Then PositionEntity Camera,EntityX(Camera)+0.3,EntityY(Camera),EntityZ(Camera) If MouseDown(1)=1 CameraPick(Camera,MouseX(),MouseY()) If PickedEntity() For ode.ODEGeom=Each ODEGeom If ode\mesh=PickedEntity() dBodyEnable(ode\body) dBodyAddForce ode\body,-20*PickedNX#(),-20*PickedNY#(),-20*PickedNZ#() End If Next End If End If If MouseDown(2)=1 CameraPick(Camera,MouseX(),MouseY()) If PickedEntity() For ode.ODEGeom=Each ODEGeom If ode\mesh=PickedEntity() dBodyEnable(ode\body) dBodyAddForce ode\body,20*PickedNX#(),20*PickedNY#(),20*PickedNZ#() End If Next End If End If End Function ; ################################################################################################### Function UpdateGeoms() For ode.ODEGeom=Each ODEGeom If ode\body 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 EndIf Next End Function ; ###################################################################################################
Here's a modifed Ragdoll demo. At this first test it seems simple joined objects work okay. Not sure why my program seemed otherwise - something to look into (maybe to do with mass?).
If you comment out all the object creation and joint creation for all limbs, leaving only head, upper and lower bodies, it bounces as high as the cube. As is, when the doll hits, though the bulk of the body hits and looking at it you'd expect a big bounce, the doll lands dead. Up the torque so it lands on it's head and the bounce is still just as limited.