JV-ODE Physics Thread 3

Blitz3D Forums/Blitz3D Userlibs/JV-ODE Physics Thread 3

What the ENTIRE progam?!?! Really what I've got is a setup phase, and then a run simulation phase which is nothing more than ODE's update. I hand over to that. At present I use something like...
Global ODE_Resolution# = 0.15

While Not KeyHit(1)
	frame=advance_simulation(frame)
	For obj.ODE_object=Each ODE_object
		Update_object(obj)
	Next
	UpdateWorld()
	RenderWorld()
	Flip
Wend


Function advance_simulation(t%)
	; Advances the simluation, incrementing frame count
	; Performs friction calculations
	; Disables 'non-existant' objects
	dSpaceCollide(ODE_space,ODE_world,ODE_contactGroup)
	
	;#Region Apply Rotational Friction
	For ode.ODE_object=Each ODE_object
		If ode\body
			If dBodyGetPositionY(ode\body)<-50.0
				dBodyDisable(ode\body)
				HideEntity ode\mesh
				HideEntity ode\outline_mesh
			EndIf
			If dBodyIsEnabled(ode\body)
				numjoints=dBodyGetNumJoints(ode\body)
				If numjoints>0 														; If joined to another body
					For joints=0 To numjoints-1								; for all joints attached to body...
						joint=dBodyGetJoint(ode\body,joints)
						If dJointGetType(joint)=dJointTypeContact		; If joint type is a collision contact
		
							; Get Angular velocity vector
					  		bx#=dBodyGetAngularVelX#(ode\body)
					  		by#=dBodyGetAngularVelY#(ode\body)
							bz#=dBodyGetAngularVelZ#(ode\body)
					  		; Calculate magnitudes
							ForceB#=Sqr(bx*bx+by*by+bz*bz)
							If forceb>.01
								friction#=ode\mat\rotational_friction*-1.0
								dBodyAddTorque ode\body,dBodyGetAngularVelX(ode\body)*friction,dBodyGetAngularVelY(ode\body)*friction,dBodyGetAngularVelZ(ode\body)*friction
							End If

						End If
					Next
				EndIf
			EndIf
		EndIf
	Next

	;#End Region
	dWorldQuickStep(ODE_world,ODE_Resolution#)
	dJointGroupEmpty(ODE_contactGroup)
	Return t+1
End Function

Function update_object(obj.ODE_Object)
	RotateEntity obj\mesh,dGeomGetPitch#(obj\geom),dGeomGetYaw#(obj\geom),dGeomGetRoll#(obj\geom)
	PositionEntity obj\mesh,dGeomGetPositionX#(obj\geom),dGeomGetPositionY#(obj\geom),dGeomGetPositionZ#(obj\geom)
End Function

I will be adding a test each frame along the lines of

For each object, If Frame = object\Entry_time, object visibile=true, ODE_active=true

This loop calls the simulation update once per iteration and so that's called 1/60th or 1/75th frame or whatever depending on screen refresh (which is something I'm a little concerned about, but not a great deal), or less than that if the simulation time overruns one frame. Simulations are nothing complex so it's not an issue on most machines but on the test case at say <30 fps main loop update the simulation runs at about half speed. If I change the quickstep value ODE_Resolution to 0.25 the low spec'd machine runs it nicely but of course it's too fast on anything more up to date.

It's not a time critical system and if the program runs slightly faster or slower on different machines that's fine. However I'd like to be able to offer at least a reasonably realistic speed even on slow machines and I know ODE can handle that if only I could figure how to tweak it.