JV-ODE Physics Thread 5

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

Here's a demo showing the use of Geom Transforms.

Each object in the demo contains 1 main sphere geom (White) and 3 sphere geom transforms (Coloured).

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

AppTitle "JV-ODE Car Demo - Geom Transform - Sphere"

Include "JV-ODE.bb"

Graphics3D 800,600,0,2

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

Global WorldERP#=1			; ### World Error Correction
Global WorldFriction#=70	; ### World Friction

Global Torque#=24			; ### Joint Torque
Global SuspensionHS#=0.01	; ### Suspension Hardness/Softness (Higher=Softer - Lower=Harder)

Global Force#=0
Global Steer#=0

Global Car
Global CGeom
Global CMesh

Global CarStartY=10

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 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()
dMassSetBoxTotal(mass,CMass,3,1,4)
dMassTranslate(mass,0,-1,0)
dBodySetMass(ode\body,mass)
dMassDestroy(mass)
ode\geom=dCreateBox(Space,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()
	dMassSetSphereTotal(mass,WMass,0.7)
	dBodySetMass(ode\body,mass)
	dMassDestroy(mass)
	ode\geom=dCreateSphere(Space,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 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(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()

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

SetupCar()

SetupObjects()

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,50,"Force:"+Force
	Text 0,65,"Torque:"+Torque
	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

Force=0

End Function

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

Function SetupObjects()

For count=1 To 30
	AddObjects((xp*34)-120,17,(zp*34)+100)

	xp=xp+1
	If xp>7
		xp=0
		zp=zp+1
		End If
Next

End Function

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

Function AddObjects(objectxp,objectyp,objectzp)

ode.ODEGeom=New ODEGeom
ode\body=dBodyCreate(World)
dBodySetRotation(ode\body,0,0,0)
dBodySetPosition(ode\body,objectxp,objectyp,objectzp)
ode\geom=dCreateSphere(Space,8)
dGeomSetBody(ode\geom,ode\body)

ode\mesh=CreateSphere()
ScaleMesh ode\mesh,8,8,8
RotateMesh ode\mesh,0,0,0
PositionMesh ode\mesh,0,0,0
EntityColor ode\mesh,255,255,255
EntityAlpha ode\mesh,0.8
EntityShininess ode\mesh,0.7

transxp=-7
transyp=0

For count=1 To 3
	TransformGeom=dCreateGeomTransform(Space)
	GeomObject=dCreateSphere(0,4)
	dGeomSetPosition(GeomObject,transxp,transyp,0)
	dGeomTransformSetGeom(TransformGeom,GeomObject)
	dGeomTransformSetCleanup(TransformGeom,1)
	dGeomSetBody(TransformGeom,ode\body)

	GeomMesh=CreateSphere(8,ode\mesh)
	ScaleMesh GeomMesh,4,4,4
	RotateMesh GeomMesh,0,0,0
	PositionMesh GeomMesh,transxp,transyp,0
	EntityColor GeomMesh,count*10,count*70,255
	EntityAlpha GeomMesh,1
	EntityShininess GeomMesh,0.7

	If count=2
		transxp=0
		transyp=-7
		Else
		transxp=transxp+14
		End If
Next

End Function

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

Function UpdateKeys()

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

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

If KeyDown(30)=0 And KeyDown(44)=0 Then Force=Force*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
	Force=0
	dBodySetRotation(Car,dGeomGetPitch#(CGeom),dGeomGetYaw#(CGeom),0)
	End If

End Function

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

Function UpdateCar()

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

dBodyEnable(Car)

For count=1 To 4
	dJointSetHinge2Param(Joint(count),dParamVel2,Force)
	dJointSetHinge2Param(Joint(count),dParamFMax2,Torque)
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,-10

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

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