OK, here's the source to the ragdoll demo. You'll need the media from the demo ZIP file, which is here - http://www.jameskett.dsl.pipex.com/Ragdoll.zip
One thing I forgot to say about the demo - you press SPACE to release the ragdoll, but you can press it again to cause him a bit more pain and make him fall apart...:)
Enjoy!
One thing I forgot to say about the demo - you press SPACE to release the ragdoll, but you can press it again to cause him a bit more pain and make him fall apart...:)
Enjoy!
;SYSTEM INIT AppTitle "TOKAMAK RAGDOLL" Graphics3D 800,600,32,2 SetBuffer BackBuffer() Color 255,255,255 SeedRnd MilliSecs() HidePointer ;CONSTANTS Const gameFPS = 60 ;frame limiting Const GRAVITY# = -10.0 ;tokamak gravity was -12.0 ;TYPES Type TYPE_array3 Field x# , y# , z# End Type Type TYPE_joint Field mesh Field id1 , id2 Field typ End Type Type TYPE_ragdoll Field TOKAMAK_active Field numparts , numjoints Field partname$[10] Field TOK_RB[10] Field TOK_geom[10] Field TOK_joint[10] Field joint.TYPE_joint[10] Field mesh[10] Field dimension.TYPE_array3[10] End Type ;TOKAMAK ENVIRONMENT SETUP TOKSIM_CreateSimulator(0,GRAVITY#,0) ;TOKAMAK GROUND PLANE Global abground = TOKAB_Create() TOKAB_AddBox abground,100.0,10.0,100.0 TOKAB_SetPosition abground,0.0,-5.0,0.0 ;BLITZ 3D SETUP ;GAME CAMERA Global camera1=CreateCamera() CameraViewport camera1,0,0,800,600 PositionEntity camera1,0,28,-28 CameraClsColor camera1,120,120,160;100,100,140 RotateEntity camera1,30,0,0 CameraZoom camera1,1.6 CameraRange camera1,0.01 , 1000.0 CameraFogMode camera1,1 CameraFogRange camera1,20 , 100 CameraFogColor camera1,120,120,160 ;LIGHTING AmbientLight 70,60,50 light1=CreateLight(1) PositionEntity light1,500,500,-500 RotateEntity light1,30,-20,0 ;RAGDOLL MARKER MESH test = LoadAnimMesh("model\ragdoll base markers.b3d") ScaleEntity test,0.1,0.1,0.1 PositionEntity test,0.75,65,0 temppivot = CreatePivot() HideEntity test Global ragdoll1.TYPE_ragdoll = New TYPE_ragdoll ragdoll1\TOKAMAK_active = False Restore DATA_ragdoll1 Read ragdoll1\numparts For a=1 To ragdoll1\numparts ragdoll1\dimension[a] = New TYPE_array3 ragdoll1\mesh[a] = CreateCube() Read ragdoll1\partname$[a] Read ragdoll1\dimension[a]\x# Read ragdoll1\dimension[a]\y# Read ragdoll1\dimension[a]\z# Read target$ e = FindChild(test,ragdoll1\partname$[a]) ScaleEntity ragdoll1\mesh[a],ragdoll1\dimension[a]\x#,ragdoll1\dimension[a]\y#,ragdoll1\dimension[a]\z# RotateEntity ragdoll1\mesh[a],0,0,0 PositionEntity ragdoll1\mesh[a],EntityX#(e,1),EntityY#(e,1),EntityZ#(e,1) EntityAlpha ragdoll1\mesh[a],0.5 EntityColor ragdoll1\mesh[a],255,255,255 If (target$ <> "") e = FindChild(test,target$) PositionEntity temppivot,EntityX#(e,1),EntityY#(e,1),EntityZ#(e,1) PointEntity ragdoll1\mesh[a] , temppivot EndIf ; EntityParent ragdoll1\mesh[a],test Next Read ragdoll1\numjoints For a=1 To ragdoll1\numjoints ragdoll1\joint[a] = New TYPE_joint Read ragdoll1\joint[a]\id1 Read ragdoll1\joint[a]\id2 Read position$ Read target$ Read ragdoll1\joint[a]\typ e = FindChild(test,position$) ragdoll1\joint[a]\mesh = CreateSphere(2) ScaleEntity ragdoll1\joint[a]\mesh,0.25,0.25,0.25 PositionEntity ragdoll1\joint[a]\mesh , EntityX#(e,1) , EntityY#(e,1) , EntityZ#(e,1) , True EntityParent ragdoll1\joint[a]\mesh , test e = FindChild(test,target$) PositionEntity temppivot,EntityX#(e,1),EntityY#(e,1),EntityZ#(e,1) PointEntity ragdoll1\joint[a]\mesh , temppivot EntityAlpha ragdoll1\joint[a]\mesh,0.5 EntityColor ragdoll1\joint[a]\mesh,255,255,0 Next .DATA_ragdoll1 Data 10 ;number of rigid bodies Data "E_BODY" , 0.25,0.6,0.15 , "" ;rigid body data - body element , dimensions x y z , target joint marker Data "E_HEAD" , 0.15,0.25,0.15 , "" Data "E_LEGL1" , 0.15,0.15,0.45 , "J_LEGL1" Data "E_LEGL2" , 0.15,0.15,0.45 , "J_LEGL2" Data "E_LEGR1" , 0.15,0.15,0.45 , "J_LEGR1" Data "E_LEGR2" , 0.15,0.15,0.45 , "J_LEGR2" Data "E_ARML1" , 0.10,0.10,0.35 , "J_ARML1" Data "E_ARML2" , 0.10,0.10,0.35 , "J_ARML2" Data "E_ARMR1" , 0.10,0.10,0.35 , "J_ARMR1" Data "E_ARMR2" , 0.10,0.10,0.35 , "J_ARMR2" Data 9 ;number of joints Data 1,2,"J_NECK" , "E_HEAD",3 Data 1,3,"J_LEGL1" , "E_BODY",1 Data 3,4,"J_LEGL2" , "E_LEGL1",3 Data 1,5,"J_LEGR1" , "E_BODY",1 Data 5,6,"J_LEGR2" , "E_LEGR1",3 Data 1,7,"J_ARML1" , "E_BODY",1 Data 7,8,"J_ARML2" , "E_ARML1",3 Data 1,9,"J_ARMR1" , "E_BODY",1 Data 9,10,"J_ARMR2" , "E_ARMR1",3 ClearTextureFilters() TextureFilter "",1 tower = LoadMesh("model\test tower 1.b3d") ScaleMesh tower,0.1,0.1,0.1 MakeTokCollider(tower) EntityPickMode tower,2 EntityColor tower,150,150,150 EntityType tower , COLTYPE_poly ClearTextureFilters() TextureFilter "",1+8 TOKSIM_SetMaterial 1,0.5,0.5 ;ragdoll body parts use this setting TOKSIM_SetMaterial 2,0.4,0.15 ;tokamak level mesh uses this setting ;INIT GAME STUFF framePeriod = 1000 / gameFPS frameTime = MilliSecs () - framePeriod MoveMouse 400,300 ;MAIN LOOP While Not KeyHit(1) ;FRAME LIMITER Repeat frameElapsed = MilliSecs () - frameTime Until frameElapsed frameTicks = frameElapsed / framePeriod frameTween# = Float (frameElapsed Mod framePeriod) / Float (framePeriod) ;MAIN LOGIC LOOP For frameLimit = 1 To frameTicks If (frameLimit = frameTicks ) CaptureWorld EndIf frameTime = frameTime + framePeriod ;LOGIC UPDATE HERE FUNC_Camera() ;CREATE A TEST TOKAMAK ENTITY If KeyHit(28) If (Not(ragdoll1\TOKAMAK_active)) FUNC_CreateRagdoll(ragdoll1) Else TOKJOINT_Free(ragdoll1\TOK_joint[2]) TOKJOINT_Free(ragdoll1\TOK_joint[4]) TOKJOINT_Free(ragdoll1\TOK_joint[6]) TOKJOINT_Free(ragdoll1\TOK_joint[8]) EndIf EndIf ;UPDATE BLITZ ENTITIES If ragdoll1\TOKAMAK_active For a=1 To ragdoll1\numparts PositionEntity ragdoll1\mesh[a],TOKRB_GetX#(ragdoll1\TOK_RB[a]),TOKRB_GetY#(ragdoll1\TOK_RB[a]),TOKRB_GetZ#(ragdoll1\TOK_RB[a]),True RotateEntity ragdoll1\mesh[a],TOKRB_GetPitch#(ragdoll1\TOK_RB[a]),TOKRB_GetYaw#(ragdoll1\TOK_RB[a]),TOKRB_GetRoll#(ragdoll1\TOK_RB[a]),True Next EndIf ;ADVANCE TOKAMAK SIMULATION TOKSIM_Advance(2.0/gameFPS,2) UpdateWorld Next ;RENDER RenderWorld FrameTween ;CALCULATE FPS If (frameTicks>0) FPS = gameFPS/frameTicks Else FPS = gameFPS EndIf Text GraphicsWidth()/2,10,"PRESS ENTER TO DROP RAGDOLL",True,True ;DISPLAY FPS ON-SCREEN Text GraphicsWidth()-55,10,"FPS:"+FPS Flip Wend ;DESTROY THE TOKAMAK SIMULATION TOKSIM_DestroySimulator() End Function FUNC_Camera() PositionEntity camera1 , 0,EntityY#(ragdoll1\mesh[1],1),0 RotateEntity camera1 , 30,camyaw#,0 MoveEntity camera1,0,0,-20 PointEntity camera1,ragdoll1\mesh[1] End Function Function FUNC_CreateRagdoll(r.TYPE_ragdoll) r\TOKAMAK_active = True For a=1 To r\numparts r\TOK_RB[a] = TOKRB_Create() r\TOK_geom[a] = TOKRB_AddBox(r\TOK_RB[a],r\dimension[a]\x# * 2,r\dimension[a]\y# * 2,r\dimension[a]\z# * 2) TOKRB_SetPosition r\TOK_RB[a],EntityX#(r\mesh[a],1),EntityY#(r\mesh[a],1),EntityZ#(r\mesh[a],1) TOKRB_SetRotation r\TOK_RB[a],EntityPitch#(r\mesh[a],1),EntityYaw#(r\mesh[a],1),EntityRoll#(r\mesh[a],1) TOKRB_SetLinearDamping r\TOK_RB[a],0.0025 TOKRB_SetAngularDamping r\TOK_RB[a],0.01 TOKRB_SetMass r\TOK_RB[a],1.0 TOKRB_SetBoxInertiaTensor r\TOK_RB[a],r\dimension[a]\x# * 2,r\dimension[a]\y# * 2,r\dimension[a]\z# * 2 , 1.0 TOKRB_CollideConnected r\TOK_RB[a] , True EntityAlpha r\mesh[a],1.0 TOKGEOM_SetMaterialIndex r\TOK_geom[a],1 ; EntityParent r\mesh[a],0 Next For a=1 To r\numjoints DebugLog "joint "+a+" created" r\TOK_joint[a] = TOKJOINT_Create( 2 , r\TOK_RB[r\joint[a]\id1] , r\TOK_RB[r\joint[a]\id2] ) TOKJOINT_SetPositionAndRotationWorld( r\TOK_joint[a] , EntityX#(r\joint[a]\mesh,1),EntityY#(r\joint[a]\mesh,1),EntityZ#(r\joint[a]\mesh,1) , EntityPitch#(r\joint[a]\mesh,1),EntityYaw#(r\joint[a]\mesh,1),EntityRoll#(r\joint[a]\mesh,1) ) TOKJOINT_SetType(r\TOK_joint[a] , r\joint[a]\typ) If (r\joint[a]\typ = 3) TOKJOINT_SetLowerLimit(r\TOK_joint[a] ,3.14 * -0.35) TOKJOINT_SetUpperLimit(r\TOK_joint[a] , 3.14 * 0.35) TOKJOINT_EnableLimit(r\TOK_joint[a] , True) EndIf TOKJOINT_Enable(r\TOK_joint[a] , True) Next ;apply a force to the body ; TOKRB_ApplyImpulse r\TOK_RB[1] , Rnd(-10.0,10.0) , Rnd(20.0) ,Rnd(20.0,100.0) End Function Function MakeTokCollider(mesh) scount=CountSurfaces(mesh) For ind=1 To scount surface=GetSurface(mesh,ind) ttltris=ttltris+CountTriangles(surface) ttlvert=ttlvert+CountVertices(surface) Next vertices=CreateBank(16*ttlvert) triangles=CreateBank(24*ttltris) offsetv=0 offsett=0 For ind=1 To scount surface = GetSurface(mesh,ind) ctr=CountTriangles(surface) tric=tric+cvt cvt=CountVertices(surface) ;fill bank with vertices For v=0 To cvt-1 PokeFloat vertices,offsetv,VertexX#(surface,v) PokeFloat vertices,offsetv+4,VertexY#(surface,v) PokeFloat vertices,offsetv+8,VertexZ#(surface,v) PokeFloat vertices,offsetv+12,0.0 offsetv=offsetv+16 Next ;fill bank with triangles For v=0 To ctr-1 PokeInt triangles,offsett,tric+TriangleVertex(surface,v,0) PokeInt triangles,offsett+4,tric+TriangleVertex(surface,v,1) PokeInt triangles,offsett+8,tric+TriangleVertex(surface,v,2) PokeInt triangles,offsett+12,2 ; Material ID PokeInt triangles,offsett+16,0 PokeInt triangles,offsett+20,0 offsett=offsett+24 Next Next ;Hand over the terrain data to Tokamak TOKSIM_SetStaticMesh vertices,ttlvert,triangles,ttltris ; Now we can free the banks as Tokamak has copied all data FreeBank vertices FreeBank triangles End Function