JV-ODE Physics Wrapper

Blitz3D Forums/Blitz3D Userlibs/JV-ODE Physics Wrapper

The forum is locked. These are the original blitzbasic.com forums, kept so they can still be read. No new topics, replies or edits can be made here. To join in, head over to the Blitz3D+ forums.

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.

; ###################################################################################################
; #									   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