JV-ODE Physics Wrapper

Blitz3D Forums/Blitz3D Userlibs/JV-ODE Physics Wrapper

Hi CopperCircle,

Ok, no problem.

1) You may be using dWorldSetContactSurfaceLayer incorrectly if it gives you a MAV (see code below)

2) Good question, dBodyGetForce along with some other functions don't return a value directly which is why you receive an Illegal Type Conversion error. You must call the function like this...

dBodyGetForce(ode\body)

Then you call the vector functions to return the value from the dBodyGetForce(ode\body) function...

forcex#=dVectorX()
forcey#=dVectorY()
forcez#=dVectorZ()

It's a little complicated at first, so I've modified the Rope Demo to show both the dWorldSetContactSurfaceLayer and dBodyGetForce functions in action...

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

AppTitle "JV-ODE - Rope Demo"

Include "ode.bb"

Graphics3D 800,600,0,2

Type ODEGeom
	Field body
	Field geom
	Field mesh
End Type

Dim Sphere(10)
Dim Joint(10)

; ###################################################################################################

; ### Setup ODE

Global World=dWorldCreate()
Global Space=dHashSpaceCreate(0)
Global ContactGroup=dJointGroupCreate(0)

dWorldSetContactSurfaceLayer(World,0.001)	; <<< Increase to reduce jittery collisions (0.0=Default)

dWorldSetAutoDisableFlag(World,1)
dWorldSetGravity(World,0,-1,0)
dContactSetMode(dContactBounce)
dContactSetBounce(0.1)
dContactSetMu(48)

; ### Create Rope

For count=1 To 10
	ode.ODEGeom=New ODEGeom
	ode\body=dBodyCreate(World)
	Sphere(count)=ode\body
	dBodySetRotation(ode\body,0,0,0)
	dBodySetPosition(ode\body,-30,90-(count*8),0)
	dBodySetAutoDisableFlag(ode\body,1)
	ode\geom=dCreateSphere(Space,4)
	dGeomSetBody(ode\geom,ode\body)
	ode\mesh=CreateSphere()
	ScaleMesh ode\mesh,4,4,4
	RotateMesh ode\mesh,0,0,0
	PositionMesh ode\mesh,0,0,0
	EntityColor ode\mesh,Rand(255),Rand(255),Rand(255)
	EntityAlpha ode\mesh,1
	EntityShininess ode\mesh,0.7
	Joint(count)=dJointCreateBall(World,0)
	If count=1
		dJointAttach(Joint(count),0,Sphere(count))
		Else
		dJointAttach(Joint(count),Sphere(count-1),Sphere(count))
		End If
	dJointSetBallAnchor(Joint(count),dBodyGetPositionX(Sphere(count)),dBodyGetPositionY(Sphere(count)),dBodyGetPositionZ(Sphere(count)))
Next

; ### 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
PositionEntity Camera,0,90,-100
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)

	UpdateKeys()

	dBodyGetForce(Sphere(10))	; <<< Use after applying force and before UpdateGeoms()

	PTime=MilliSecs()

	If MilliSecs()-Timer>700
		AddObject()
		Timer=MilliSecs()
		End If

	UpdateGeoms()

	dSpaceCollide(Space,World,ContactGroup)
	dWorldQuickStep(World,0.1)
	dJointGroupEmpty(ContactGroup)

	PhysicsTime#=MilliSecs()-PTime

	UpdateWorld

	RenderWorld

	Text 0,0,"JV-ODE Version "+dGetVersion()
	Text 0,15,"Physics Time:"+PhysicsTime
	Text 640,0,"Add Force To Rope"
	Text 640,15,"Using Arrow Keys"

	Text 0,40,"VectorX:"+dVectorX()		; <<< Returned Vectors from dBodyGetForce()
	Text 0,55,"VectorY:"+dVectorY()
	Text 0,70,"VectorZ:"+dVectorZ()

	Text 0,95,"Contact Surface Layer:"+dWorldGetContactSurfaceLayer(World)

	Flip

Wend

dJointGroupDestroy(ContactGroup)
dSpaceDestroy(Space)
dWorldDestroy(World)
dCloseODE()

End

; ###################################################################################################

Function AddObject()

ode.ODEGeom=New ODEGeom
ode\body=dBodyCreate(World)
dBodySetRotation(ode\body,0,0,0)
dBodySetPosition(ode\body,30,80,0)
dBodySetAutoDisableFlag(ode\body,1)
ode\geom=dCreateBox(Space,10,5,10)
dGeomSetBody(ode\geom,ode\body)
ode\mesh=CreateCube()
ScaleMesh ode\mesh,5,2.5,5
EntityColor ode\mesh,Rand(255),Rand(255),Rand(255)
EntityAlpha ode\mesh,1
EntityShininess ode\mesh,0.7

End Function

; ###################################################################################################

Function UpdateKeys()

If KeyDown(203) Then dBodyAddForce(Sphere(10),-10,0,0)
If KeyDown(205) Then dBodyAddForce(Sphere(10),10,0,0)
If KeyDown(200) Then dBodyAddForce(Sphere(10),0,0,10)
If KeyDown(208) Then dBodyAddForce(Sphere(10),0,0,-10)

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)
		End If
Next

End Function

; ###################################################################################################


Let me know if you need any more help with this :)