Hi All,
Just beginning with ODE and here a experiment with breakable tables (yes, based on code you guys did before, so nothing new). I'm curious to know if you guys know any other ways to 'get bodies to relax' and auto disable themselves.
In the demo you can see when you've got lots of objects stacked on top of each other they keep bouncing around amongst each other. Lowering angular&linear thresholds can only go so far untill bodies come to rest in an unrealistic pose...
cheers,
Danny
p.s. How do you post a small box with code in it? unlike this big chunk:
Just beginning with ODE and here a experiment with breakable tables (yes, based on code you guys did before, so nothing new). I'm curious to know if you guys know any other ways to 'get bodies to relax' and auto disable themselves.
In the demo you can see when you've got lots of objects stacked on top of each other they keep bouncing around amongst each other. Lowering angular&linear thresholds can only go so far untill bodies come to rest in an unrealistic pose...
cheers,
Danny
p.s. How do you post a small box with code in it? unlike this big chunk:
Include "JV-ODE.bb" ; DANNY's Broken Table Test Const ANGTHRESH# = 0.1 ;default auto disable angular threshold Const LINTHRESH# = 0.1 ;default auto disable linear threshold Const STEPTHRESH = 1 Graphics3D 800,600,0,2 Type odeGeom Field body Field geom Field mesh Field lastForce# End Type ; ################################################################################################### ; ### Setup ODE Global World=dWorldCreate() Global Space=dHashSpaceCreate(0) Global ContactGroup=dJointGroupCreate(0) dWorldSetGravity(World,0,-0.48,0) dWorldSetERP World, 0.25 dContactSetMu(40) SeedRnd 666 Global camera, camerapivot Create3D() ;add some random tables r#=1 addTable -3,2,3, 2,1,2 addTable 3,2,3, 2,1,2 addTable -3,2,-3, 2,1,2 addTable 3,2,-3, 2,1,2 addTable 0,3,0, 2,1,2 ; ################################################################################################### ;sfx = Load3DSound("bin\woodimpact02.wav") ;Global break = Load3DSound("bin\Door.wav") ;CreateListener camera goSim = False fps = 0 frames = 0 ftime = MilliSecs()+1000 While Not KeyHit(1) ;make dizzy TurnEntity camerapivot, 0, 0.1, 0 ;ENTER = more boxes If KeyDown(28) Then AddObject(Rand(-r,r),Rand(-r,r)) ;SPACE = more tables If KeyHit(57) Then AddTable(Rand(-r,r),Rand(3,6),Rand(-r,r),2,1,2) If goSim Then ;add random boxes every couple ms If MilliSecs()-BoxTimer>50 numbox=numbox+1 ;limit amount of boxes If numbox < 50 Then r# =4 AddObject(Rand(-r,r),Rand(-r,r)) EndIf BoxTimer=MilliSecs() End If ;- PTime=MilliSecs() dSpaceCollide(Space,World,ContactGroup) dWorldQuickStep(World,0.1) dJointGroupEmpty(ContactGroup) PhysicsTime#=MilliSecs()-PTime ;check for breakage JointLimits(1.5) EndIf UpdateGeoms() UpdateWorld RenderWorld ;fps check If MilliSecs() >=ftime Then goSim = True ;delay simulation with a second fps=frames frames=0 ftime=MilliSecs()+999 Else frames=frames+1 EndIf ;debug Color 250,250,250 Text 5,0,"JV-ODE Version "+dGetVersion() Text 5,15,"Physics Time:"+PhysicsTime Text 5,30,"FPS: "+FPS Text GraphicsWidth()/2,50,"GREEN objects are ENABLED/ACTIVE - RED objects are DISABLED", 1 Text GraphicsWidth()/2,65,"Press ENTER for more boxes", 1 Text GraphicsWidth()/2,80,"Press SPACEBAR to add a Breakable Table!", 1 ;show Flip 1 Wend dJointGroupDestroy(ContactGroup) dSpaceDestroy(Space) dWorldDestroy(World) dCloseODE() End ; ################################################################################################### Function Create3D() ;| Default 3d scene ; ### Create light Light=CreateLight() RotateEntity Light,45,-90,0 LightColor Light,255,255,255 AmbientLight 130,130,130 ; ### Create camera camerapivot = CreatePivot() Camera=CreateCamera(camerapivot) CameraClsColor Camera,0,0,0 CameraRange Camera,0.01,250 PositionEntity Camera,-5,7,-7 PositionEntity camerapivot, 0,1,0 PointEntity camera, camerapivot ;make top text readable CameraFogColor camera, 0,0,0 CameraFogRange camera, 5,30 CameraFogMode camera, 1 ; ### Create plane dCreatePlane(Space,0,1,0,0) Plane=CreatePlane() EntityAlpha Plane,0.95 PlaneTexture=CreateTexture(128,128,9) ClsColor 220,210,200 Cls Color 150,120,110 Rect 0,0,64,64,1 Rect 64,64,64,64,1 CopyRect 0,0,128,128,0,0,BackBuffer(),TextureBuffer(PlaneTexture) ScaleTexture PlaneTexture,5,5 EntityTexture Plane,PlaneTexture,0,0 Mirror=CreateMirror() Color 255,255,255 End Function ; ################################################################################################### Function AddObject(xp#=666,zp#=666) size# = Rnd#(0.25,0.65) range# = 0.5 If xp=666 Then xp=Rand(-range#,range#) yp=Rand(7,15) If zp=666 Then zp=Rand(-range#,range#) ode.ODEGeom=New ODEGeom ode\body=dBodyCreate(World) dBodySetRotation(ode\body,0,0,0) dBodySetPosition(ode\body,xp,yp,zp) dBodySetAutoDisableFlag(ode\body,1) dBodySetAutoDisableLinearThreshold ode\body, LINTHRESH dBodySetAutoDisableAngularThreshold ode\body, ANGTHRESH dBodySetAutoDisableSteps ode\body, STEPTHRESH ode\geom=dCreateBox(Space,size#,size#,size#) dGeomSetBody(ode\geom,ode\body) ode\mesh=CreateCube() ScaleMesh ode\mesh,size#/2,size#/2,size#/2 EntityColor ode\mesh,Rand(255),Rand(255),Rand(255) EntityAlpha ode\mesh,1 EntityShininess ode\mesh,0.7 mass = dMassCreate() dMassSetBoxTotal mass, 25.0, size#,size#,size# dBodySetMass ode\body, mass dMassDestroy mass End Function ; ################################################################################################### Function AddTable(xp#, yp#, zp#, w#,h#,d#) ;# Creates a table with 4 legs - breakable legs! :) w# = Rnd(w#*0.5,w#*1.5) ;add some variation to the table's dimensions h# = Rnd(h#*0.5,h#*1.5) d# = Rnd(d#*0.5,d#*1.5) ;table top dimensions th# = h# * 0.1 ;leg dimensions lw# = w#*0.1 lh# = h#*0.9 ld# = d#*0.1 ;create tabletop ode.odegeom = New odegeom ode\body = dBodyCreate(world) dBodySetPosition ode\body, xp#, yp#, zp# dBodySetRotation ode\body, 0,0,0 dBodySetAutoDisableFlag ode\body, 1 dBodySetAutoDisableLinearThreshold ode\body, LINTHRESH dBodySetAutoDisableAngularThreshold ode\body, ANGTHRESH dBodySetAutoDisableSteps ode\body, STEPTHRESH ode\geom=dCreateBox(space,w#,th#,d#) dGeomSetBody ode\geom, ode\body ode\mesh=CreateCube() EntityColor ode\mesh, 100,50,0 ScaleMesh ode\mesh, w#/2,th#/2,d#/2 tableBody = ode\body ; yp# = yp# - 0.01 ;-> create small gap between table top & legs ;create leg 1 ode.odegeom = New odegeom ode\body = dBodyCreate(world) dBodySetPosition ode\body, xp#-w#/2+lw#/2, yp#-lh#/2-th#/2, zp#-d#/2+ld#/2 dBodySetRotation ode\body, 0,0,0 dBodySetAutoDisableFlag ode\body, 1 dBodySetAutoDisableLinearThreshold ode\body, LINTHRESH dBodySetAutoDisableAngularThreshold ode\body, ANGTHRESH dBodySetAutoDisableSteps ode\body, STEPTHRESH ode\geom=dCreateBox(space,lw#,lh#,ld#) dGeomSetBody ode\geom, ode\body ode\mesh=CreateCube() EntityColor ode\mesh, 200,100,0 ScaleMesh ode\mesh, lw#/2,lh#/2,ld#/2 ;join the legs to the table joint = dJointCreateHinge(world,0) dJointAttach joint, tableBody, ode\body dJointSetHingeAxis joint, -1,0,0 dJointSetHingeAnchor joint, xp#-w#/2+lw#/2, yp#-th#/2, zp#-d#/2+ld#/2 dJointSetHingeParam joint, dParamLoStop, 0 dJointSetHingeParam joint, dParamHiStop, 0 ;create leg 2 ode.odegeom = New odegeom ode\body = dBodyCreate(world) dBodySetPosition ode\body, xp#+w#/2-lw#/2, yp#-lh#/2-th#/2, zp#-d#/2+ld#/2 dBodySetRotation ode\body, 0,0,0 dBodySetAutoDisableFlag ode\body, 1 dBodySetAutoDisableLinearThreshold ode\body, LINTHRESH dBodySetAutoDisableAngularThreshold ode\body, ANGTHRESH dBodySetAutoDisableSteps ode\body, STEPTHRESH ode\geom=dCreateBox(space,lw#,lh#,ld#) dGeomSetBody ode\geom, ode\body ode\mesh=CreateCube() EntityColor ode\mesh, 200,100,0 ScaleMesh ode\mesh, lw#/2,lh#/2,ld#/2 ;join the legs to the table joint = dJointCreateHinge(world,0) dJointAttach joint, tableBody, ode\body dJointSetHingeAxis joint, -1,0,0 dJointSetHingeAnchor joint, xp#+w#/2-lw#/2, yp#-th#/2, zp#-d#/2+ld#/2 dJointSetHingeParam joint, dParamLoStop, -0.0 dJointSetHingeParam joint, dParamHiStop, 0.0 ;create leg 3 ode.odegeom = New odegeom ode\body = dBodyCreate(world) dBodySetPosition ode\body, xp#+w#/2-lw#/2, yp#-lh#/2-th#/2, zp#+d#/2-ld#/2 dBodySetRotation ode\body, 0,0,0 dBodySetAutoDisableFlag ode\body, 1 dBodySetAutoDisableLinearThreshold ode\body, LINTHRESH dBodySetAutoDisableAngularThreshold ode\body, ANGTHRESH dBodySetAutoDisableSteps ode\body, STEPTHRESH ode\geom=dCreateBox(space,lw#,lh#,ld#) dGeomSetBody ode\geom, ode\body ode\mesh=CreateCube() EntityColor ode\mesh, 200,100,0 ScaleMesh ode\mesh, lw#/2,lh#/2,ld#/2 ;join the legs to the table joint = dJointCreateHinge(world,0) dJointAttach joint, tableBody, ode\body dJointSetHingeAxis joint, -1,0,0 dJointSetHingeAnchor joint, xp#+w#/2-lw#/2, yp#-th#/2, zp#+d#/2-ld#/2 dJointSetHingeParam joint, dParamLoStop, -0.0 dJointSetHingeParam joint, dParamHiStop, 0.0 ;create leg 4 ode.odegeom = New odegeom ode\body = dBodyCreate(world) dBodySetPosition ode\body, xp#-w#/2+lw#/2, yp#-lh#/2-th#/2, zp#+d#/2-ld#/2 dBodySetRotation ode\body, 0,0,0 dBodySetAutoDisableFlag ode\body, 1 dBodySetAutoDisableLinearThreshold ode\body, LINTHRESH dBodySetAutoDisableAngularThreshold ode\body, ANGTHRESH dBodySetAutoDisableSteps ode\body, STEPTHRESH ode\geom=dCreateBox(space,lw#,lh#,ld#) dGeomSetBody ode\geom, ode\body ode\mesh=CreateCube() EntityColor ode\mesh, 200,100,0 ScaleMesh ode\mesh, lw#/2,lh#/2,ld#/2 ;join the legs to the table joint = dJointCreateHinge(world,0) dJointAttach joint, tableBody, ode\body dJointSetHingeAxis joint, -1,0,0 dJointSetHingeAnchor joint, xp#-w#/2+lw#/2, yp#-th#/2, zp#+d#/2-ld#/2 dJointSetHingeParam joint, dParamLoStop, -0.0 dJointSetHingeParam joint, dParamHiStop, 0.0 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) EntityColor ode\mesh, 0,255,0 Else EntityColor ode\mesh, 255,0,0 End If ;remove if object falls off the world If dGeomGetPositionY#(ode\geom) < -100 Then DebugLog "body "+Handle(ode)+" deleted" dGeomDestroy ode\geom dBodyDestroy ode\body FreeEntity ode\mesh Delete ode EndIf Next End Function ; ################################################################################################### Function JointLimits(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 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) ; Check for sudden deceleration If Abs((ode\LastForce#-forceA#))>limit Then ;dJointAttach(joint,0,0) dJointDestroy joint ; EmitSound break, ode\mesh End If ode\LastForce#=ForceA# End If End If Next End If ;End If End If Next End Function