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.

This modified sphere demo lets you push and pull the balls around with the mouse. Also demonstrates the autodisable feature to reduce physics overhead.

enjoy
; ###################################################################################################
; #									   JV-ODE - Spheres Demo										#
; #									Code by Jim Williams (VIP3R)									#
; ###################################################################################################

AppTitle "JV-ODE - Spheres Mouse Shot 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(dContactBounce + ContactSoftERP + dContactSoftCFM)
dContactSetMu(32)

; Autodisable bodies
dWorldSetAutoDisableFlag (World, 1)

; Increase to make bouncy
dContactSetBounce(0.3)

; Make contact surface soft
;dContactSetSoftERP(0.4)
;dContactSetSoftCFM(0.8)


; ### Create light

ShowPointer

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
		balls=balls+1
		If balls<10 Then
				AddObject()
		End If
		Timer=MilliSecs()
		End If

	UpdateGeoms()

	PhysicsTime#=MilliSecs()-PTime

	UpdateWorld

	RenderWorld

	Text 0,0,"JV-ODE Version "+dGetVersion()
	Text 0,15,"Physics Time:"+PhysicsTime
	Text 0,35,"LM Push: "
	Text 0,50,"RM Pull: "
 


	Flip
	
	
	; Push on the ball based on the entitypicked vector
	If MouseDown(1) Then 
	
		CameraPick(camera, MouseX(), MouseY())
		
		If PickedEntity()<>0 Then
			EntityColor PickedEntity(),0,255,0
			For ode.ODEGeom=Each ODEGeom
				If ode\mesh=PickedEntity()
					dBodyEnable(ode\body) 
					k=-10
					dBodyAddForce ode\body,k*PickedNX#(),k*PickedNY#(),k*PickedNZ#()
					Exit
				End If
			Next
		End If
	End If
	
	; Pull on the ball based on the entitypicked vector
	If MouseDown(2) Then 
	
		CameraPick(camera, MouseX(), MouseY())
		
		If PickedEntity()<>0 Then
			EntityColor PickedEntity(),0,255,0
			For ode.ODEGeom=Each ODEGeom
				If ode\mesh=PickedEntity()
					dBodyEnable(ode\body) 
					k=10
					dBodyAddForce ode\body,k*PickedNX#(),k*PickedNY#(),k*PickedNZ#()
					Exit
				End If
			Next
		End If
	End If

	

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

;Set Autodisable parms to your liking
	dBodySetAutoDisableFlag(ode\body,1)
	dBodySetAutoDisableAngularThreshold(ode\body,.05)
	dBodySetAutoDisableLinearThreshold(ode\body,.05)
	dBodySetAutoDisableSteps (ode\body, 1)

;Allow sphere to be picked
EntityPickMode ode\mesh,2

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)
Else
	EntityColor ode\mesh,255,0,0
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 dBodyIsEnabled(ode\body)
		numjoints=dBodyGetNumJoints(ode\body)
		If numjoints>0 
		
			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