JV-ODE Physics Thread 3

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

@Wayne: Nice one ;)

Here you go Shifty Geezer, the CarDemo-MultipleSpace.bb example is still included in the library...

; ###################################################################################################
; #										  JV-ODE Car Demo											#
; #									Code by Jim Williams (VIP3R)									#		#
; #						Feel free to use this code, any credit appreciated							#
; ###################################################################################################

AppTitle "JV-ODE Car Demo"

Include "JV-ODE.bb"

Graphics3D 800,600,0,2

Global CMass#=200			; ### Car Mass
Global WMass#=8				; ### Wheel Mass

Global WorldERP#=1			; ### World Error Correction
Global WorldFriction#=64	; ### World Friction
Global HingeTorque#=24		; ### Hinge Torque
Global SuspensionHS#=0.01	; ### Hinge Suspension Hardness/Softness (Higher=Softer - Lower=Harder)

Global Speed#=0
Global Steer#=0

Global Car
Global CGeom
Global CMesh

Global CarStartY=20

Dim Wheel(4)
Dim WGeom(4)
Dim Joint(4)

Type ODEGeom
	Field body
	Field geom
	Field mesh
End Type

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

; ### Setup ODE

Global World=dWorldCreate()
Global Space=dHashSpaceCreate(0)
Global CarSpace=dHashSpaceCreate(Space)
Global RampSpace=dHashSpaceCreate(Space)
Global SceneSpace=dHashSpaceCreate(Space)
Global ContactGroup=dJointGroupCreate(0)

dWorldSetAutoDisableFlag(World,1)
dWorldSetGravity(World,0,-0.98,0)
dWorldSetERP(World,WorldERP)

dContactSetMode(dContactSlip1)
dContactSetMu(WorldFriction)

; ### Create car body

ode.ODEGeom=New ODEGeom
ode\body=dBodyCreate(World)
Car=ode\body
dBodySetRotation(ode\body,0,0,0)
dBodySetPosition(ode\body,0,CarStartY,0)
mass=dMassCreate()
dMassSetBox(mass,1,3,1,4)
dMassSetBoxTotal(mass,CMass,3,1,4)
dMassTranslate(mass,0,-1,0)
dBodySetMass(ode\body,mass)
dMassDestroy(mass)
ode\geom=dCreateBox(CarSpace,3,1,4)
CGeom=ode\geom
dGeomSetBody(ode\geom,ode\body)
ode\mesh=CreateCube()
CMesh=ode\mesh
ScaleMesh ode\mesh,1.5,0.5,2
RotateMesh ode\mesh,0,0,0
PositionMesh ode\mesh,0,0,0
EntityColor ode\mesh,40,80,255
EntityAlpha ode\mesh,1

; ### Create wheels

For count=1 To 4
	ode.ODEGeom=New ODEGeom
	ode\body=dBodyCreate(World)
	Wheel(count)=ode\body
	dBodySetRotation(ode\body,0,0,0)
	dBodySetPosition(ode\body,0,0,0)
	mass=dMassCreate()
	dMassSetSphere(mass,1,0.7)
	dMassSetSphereTotal(mass,WMass,0.7)
	dBodySetMass(ode\body,mass)
	dMassDestroy(mass)
	ode\geom=dCreateSphere(CarSpace,0.7)
	WGeom(count)=ode\geom
	dGeomSetBody(ode\geom,ode\body)
	ode\mesh=CreateCylinder(8)
	ScaleMesh ode\mesh,0.7,0.25,0.7
	RotateMesh ode\mesh,0,0,90
	PositionMesh ode\mesh,0,0,0
	EntityColor ode\mesh,255,255,255
Next

dBodySetPosition(Wheel(1),-2,CarStartY-0.5,+2)
dBodySetPosition(Wheel(2),+2,CarStartY-0.5,+2)
dBodySetPosition(Wheel(3),-2,CarStartY-0.5,-2)
dBodySetPosition(Wheel(4),+2,CarStartY-0.5,-2)

; ### Create some objects

SeedRnd MilliSecs()

For spheres=1 To 20
	ode.ODEGeom=New ODEGeom
	ode\body=dBodyCreate(World)
	dBodySetRotation(ode\body,0,0,0)
	dBodySetPosition(ode\body,Rnd(-100,100),30,Rnd(-100,100))
	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,Rnd(255),Rnd(255),Rnd(255)
	EntityAlpha ode\mesh,1
	EntityShininess ode\mesh,0.7
Next

For cylinders=1 To 20
	ode.ODEGeom=New ODEGeom
	ode\body=dBodyCreate(World)
	dBodySetRotation(ode\body,90,0,0)
	dBodySetPosition(ode\body,Rnd(-100,100),30,Rnd(-100,100))
	ode\geom=dCreateCCylinder(Space,1,8)
	dGeomSetBody(ode\geom,ode\body)
	ode\mesh=CreateCylinder(8)
	ScaleMesh ode\mesh,1,5,1
	RotateMesh ode\mesh,90,0,0	; <<< Mesh X-Axis must be rotated 90 degrees to fix cylinder alignment
	PositionMesh ode\mesh,0,0,0
	EntityColor ode\mesh,Rnd(255),Rnd(255),Rnd(255)
	EntityAlpha ode\mesh,1
	EntityShininess ode\mesh,0.7
Next

; ### Create light

Global Light=CreateLight()

RotateEntity Light,45,-90,0
LightColor Light,255,255,255
AmbientLight 130,130,130

; ### Create camera

Global CameraPivot=CreatePivot(CMesh)
PositionEntity CameraPivot,0,2,-7

Global Camera=CreateCamera()
CameraClsColor Camera,0,0,0
CameraRange Camera,1,1000

; ### Create plane

dCreatePlane(SceneSpace,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()

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

; ### BLITZ STATIC OBJECT (White)

blitzobject=CreateCube()
ScaleMesh blitzobject,1,4,20
RotateMesh blitzobject,-10,8,4
PositionMesh blitzobject,10,5,40

EntityColor blitzobject,255,255,255
EntityAlpha blitzobject,1

; ### ODE STATIC OBJECT (Blue)

ode.ODEGeom=New ODEGeom
ode\geom=dCreateBox(SceneSpace,2,8,40)
dGeomSetRotation(ode\geom,-10,8,4)
dGeomSetPosition(ode\geom,20,5,40)
ode\mesh=CreateCube()
ScaleMesh ode\mesh,1,4,20
RotateMesh ode\mesh,0,0,0
PositionMesh ode\mesh,0,0,0

EntityColor ode\mesh,0,100,200
EntityAlpha ode\mesh,1

; ### ODE STATIC OBJECT (Red)

ode.ODEGeom=New ODEGeom
ode\geom=dCreateBox(CarSpace,18,0.2,40)
dGeomSetRotation(ode\geom,-14,0,0)
dGeomSetPosition(ode\geom,-20,4.9,40)
ode\mesh=CreateCube()
ScaleMesh ode\mesh,9,0.1,20
RotateMesh ode\mesh,0,0,0
PositionMesh ode\mesh,0,0,0

EntityColor ode\mesh,200,0,100
EntityAlpha ode\mesh,1

; ### ODE STATIC OBJECT (Green)

ode.ODEGeom=New ODEGeom
ode\geom=dCreateBox(RampSpace,18,0.2,40)
dGeomSetRotation(ode\geom,-14,0,0)
dGeomSetPosition(ode\geom,-45,4.9,40)
ode\mesh=CreateCube()
ScaleMesh ode\mesh,9,0.1,20
RotateMesh ode\mesh,0,0,0
PositionMesh ode\mesh,0,0,0

EntityColor ode\mesh,0,200,100
EntityAlpha ode\mesh,1

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

SetupCar()

While Not KeyHit(1)

	UpdateKeys()

	PTime=MilliSecs()

	UpdateCar()

	UpdateGeoms()

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

	PhysicsTime#=MilliSecs()-PTime

	UpdateCam()

	UpdateWorld

	RenderWorld

	Text 0,0,"JV-ODE Version "+dGetVersion()
	Text 0,15,"Physics Time:"+PhysicsTime
	Text 0,30,"Car Speed:"+Speed
	Text 0,435,"Object:        In Space (Geoms):"
	Text 0,455,"Car            CarSpace ("+dSpaceGetNumGeoms(CarSpace)+")"
	Text 0,470,"Red Ramp       CarSpace ("+dSpaceGetNumGeoms(CarSpace)+")"
	Text 0,485,"Green Ramp     RampSpace ("+dSpaceGetNumGeoms(RampSpace)+")"
	Text 0,500,"Blue Block     SceneSpace ("+dSpaceGetNumGeoms(SceneSpace)+")"
	Text 0,515,"Ground Plane   SceneSpace ("+dSpaceGetNumGeoms(SceneSpace)+")"
	Text 0,530,"20 Spheres     Space (Top Level - "+dSpaceGetNumGeoms(Space)+")"
	Text 0,545,"20 CCylinders  Space (Top Level - "+dSpaceGetNumGeoms(Space)+")"

	Text 225,0,"F1 - Toggle Internal Space Collide Mode ("+dGetInternalSpaceCollideMode()+")"
	If dGetInternalSpaceCollideMode()=1
		Text 255,20,"ENABLED - Red Ramp & Car DO Collide"
		Else
		Text 235,20,"DISABLED - Red Ramp & Car DO NOT Collide"
		End If

	Text 640,0,"A - Accelerate"
	Text 640,15,"Z - Brake/Reverse"
	Text 640,30,"Arrows - Steering"
	Text 640,45,"Space - Reset Car"

	Flip

Wend

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

End

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

Function SetupCar()

For count=1 To 4
	Joint(count)=dJointCreateHinge2(World,0)
	dJointAttach(Joint(count),Car,Wheel(count))
	dJointSetHinge2Anchor(Joint(count),dBodyGetPositionX(Wheel(count)),dBodyGetPositionY(Wheel(count)),dBodyGetPositionZ(Wheel(count)))
	dJointSetHinge2Axis1(Joint(count),0,1,0)
	dJointSetHinge2Axis2(Joint(count),-1,0,0)
	dJointSetHinge2Param(Joint(count),dParamSuspensionERP,0.8)
	dJointSetHinge2Param(Joint(count),dParamSuspensionCFM,SuspensionHS)
	If count>2
		dJointSetHinge2Param(Joint(count),dParamLoStop,0)
		dJointSetHinge2Param(Joint(count),dParamHiStop,0)
		End If
Next

Speed=0

End Function

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

Function UpdateKeys()

If KeyDown(30)=1
	Speed=Speed+0.08
	If Speed>30 Then Speed=30
	End If

If KeyDown(44)=1
	Speed=Speed-0.1
	If Speed<-10 Then Speed=-10
	If Speed>0 Then Speed=Speed*0.97
	End If

If KeyDown(30)=0 And KeyDown(44)=0 Then Speed=Speed*0.99

If KeyDown(203)=1 Or KeyDown(205)=1
	If KeyDown(203)=1
		Steer=0.5
		Else
		Steer=-0.5
		End If
	Else
	Steer=0
	End If

If KeyHit(57)=1
	Speed=0
	dBodySetRotation(Car,0,0,0)
	End If

If KeyHit(59)=1 Then dSetInternalSpaceCollideMode(Not dGetInternalSpaceCollideMode())

End Function

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

Function UpdateCar()

For count=1 To 4
	dBodyEnable(Wheel(count))
Next

dBodyEnable(Car)

For count=1 To 4
	dJointSetHinge2Param(Joint(count),dParamVel2,Speed)
	dJointSetHinge2Param(Joint(count),dParamFMax2,HingeTorque)
Next

For count=1 To 2
	angle#=Steer-dJointGetHinge2Angle1(Joint(count))
	dJointSetHinge2Param(Joint(count),dParamVel,angle)
	dJointSetHinge2Param(Joint(count),dParamFMax,400)
Next

End Function

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

Function UpdateCam()

PositionEntity CameraPivot,0,3,-12

camx#=EntityX(CameraPivot,1)-EntityX(Camera)
camy#=EntityY(CameraPivot,1)-EntityY(Camera)
camz#=EntityZ(CameraPivot,1)-EntityZ(Camera)

TranslateEntity Camera,camx*0.5,camy*0.5,camz*0.5

PointEntity Camera,CMesh

End Function

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

Function UpdateGeoms()

For ode.ODEGeom=Each ODEGeom
	RotateEntity ode\mesh,dGeomGetPitch#(ode\geom),dGeomGetYaw#(ode\geom),dGeomGetRoll#(ode\geom)
	PositionEntity ode\mesh,dGeomGetPositionX#(ode\geom),dGeomGetPositionY#(ode\geom),dGeomGetPositionZ#(ode\geom)
Next

End Function

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