I learned that one should check collisions before stepping the world. The article is here:
http://www.cambrianlabs.com/mattias/DelphiODE/UsingDelphiODE.asp
Revised Spheres Demo to collision check before WorldQuickStep, and add friction on each collision contact. Not sure if autodisable is working for me in this example or not. Nice simulation.
Lots of new ODE stuff to learn and try.
http://www.cambrianlabs.com/mattias/DelphiODE/UsingDelphiODE.asp
Revised Spheres Demo to collision check before WorldQuickStep, and add friction on each collision contact. Not sure if autodisable is working for me in this example or not. Nice simulation.
Lots of new ODE stuff to learn and try.
; ################################################################################################### ; # JV-ODE - Spheres Demo # ; # Code by Jim Williams (VIP3R) # ; ################################################################################################### AppTitle "JV-ODE - Spheres Demo" Global snd1, piv1 Include "ode.bb" Graphics3D 800,600,0,2 Type ODEGeom Field body Field geom Field mesh End Type ; ################################################################################################### ;snd1=Load3DSound("Bounce.wav") ;piv1=CreatePivot() ; ### Setup ODE Global World=dWorldCreate() Global Space=dHashSpaceCreate(0) Global ContactGroup=dJointGroupCreate(0) dWorldSetGravity(World,0,-1,0) dContactSetMode(dContactBounced + ContactSoftERP + dContactSoftCFM) dContactSetMu(32) ; Increase to make bouncy dContactSetBounce(0.3) ; Make contact surface soft ;dContactSetSoftERP(0.4) ;dContactSetSoftCFM(0.8) ; ### 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 ;mic1=CreateListener(camera) ; Create listener, make it child of camera PositionEntity Camera,0,20,-50 RotateEntity Camera,30,0,0 ; ### Create plane dCreatePlane(Space,0,1,0,0) Plane=CreatePlane() EntityAlpha Plane,0.8 PlaneTexture=CreateTexture(128,128,9) ClsColor 0,200,80 Cls Color 255,255,255 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 Mirror=CreateMirror() ; ################################################################################################### While Not KeyHit(1) PTime=MilliSecs() dSpaceCollide(Space,World,ContactGroup) UpdateFriction dWorldQuickStep(World,0.1) dJointGroupEmpty(ContactGroup) If MilliSecs()-Timer>700 AddObject() Timer=MilliSecs() End If UpdateGeoms() PhysicsTime#=MilliSecs()-PTime UpdateWorld RenderWorld Text 0,0,"JV-ODE Version "+dGetVersion() Text 0,15,"Physics Time:"+PhysicsTime Flip Wend dJointGroupDestroy(ContactGroup) dSpaceDestroy(Space) dWorldDestroy(World) dCloseODE() End ; ################################################################################################### Function AddObject() xp=Rand(-8,8) zp=Rand(-8,8) ode.ODEGeom=New ODEGeom ode\body=dBodyCreate(World) dBodySetRotation(ode\body,0,0,0) dBodySetPosition(ode\body,xp,30,zp) ode\geom=dCreateSphere(Space,3) dGeomSetBody(ode\geom,ode\body) ode\mesh=CreateSphere() ScaleMesh ode\mesh,3,3,3 EntityColor ode\mesh,Rand(255),Rand(255),Rand(255) EntityAlpha ode\mesh,1 EntityShininess ode\mesh,0.7 End Function ; ################################################################################################### Function UpdateGeoms() For ode.ODEGeom=Each ODEGeom If dGeomIsEnabled(ode\geom) 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 AngularDamp(body,damp#) dBodyAddTorque body,dBodyGetAngularVelX(body)*-damp,dBodyGetAngularVelY(body)*-damp,dBodyGetAngularVelZ(body)*-damp End Function ; ################################################################################################### Function LinearDamp(body,damp#) dBodyAddForce body,dBodyGetLinearVelX(body)*-damp,dBodyGetLinearVelY(body)*-damp,dBodyGetLinearVelZ(body)*-damp End Function ; ################################################################################################### Function UpdateFriction() For ode.ODEGeom=Each ODEGeom If dGeomIsEnabled(ode\geom) numjoints=dBodyGetNumJoints(ode\body) If numjoints>0 DebugLog "joints=" + Str(joints) For joints=0 To numjoints-1 joint=dBodyGetJoint(ode\body,joints) 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) If ForceA>.01 LinearDamp(ode\body,.08) End If If ForceB>.01 AngularDamp(ode\body,.08) End If End If Next End If End If Next End Function