jv-ode more than one car

Blitz3D Forums/Blitz3D Userlibs/jv-ode more than one car

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.

Here's a two car demo with simple AI controlling the second car.

The 'Force' variable is changed to an array, one for each car...
; ###################################################################################################
; #										JV-ODE Twin Car Demo										#
; #									Code by Jim Williams (VIP3R)									#
; #								Devious Codeworks - Copyright © 2007								#
; ###################################################################################################

AppTitle "JV-ODE Twin Car Demo"

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 CarAmount=2
Global ControlTimer=0
Global SteeringTimer=0

Dim Force#(CarAmount)
Dim Steer#(CarAmount)

Dim Car(CarAmount)
Dim CGeom(CarAmount)
Dim CMesh(CarAmount)

Global CarStartY=20

Dim Wheel(CarAmount,4)
Dim WGeom(CarAmount,4)
Dim Joint(CarAmount,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)

For CarID=1 To 2

	; ### Create car body

	ode.ODEGeom=New ODEGeom
	ode\body=dBodyCreate(World)
	Car(CarID)=ode\body
	dBodySetRotation(ode\body,0,0,0)
	dBodySetPosition(ode\body,CarID*10,CarStartY,0)
	mass=dMassCreate()
	dMassSetBoxTotal(mass,CMass,3,1,4)
	dBodySetMass(ode\body,mass)
	dMassDestroy(mass)
	ode\geom=dCreateBox(Space,3,1,4)
	CGeom(CarID)=ode\geom
	dGeomSetBody(ode\geom,ode\body)
	ode\mesh=CreateCube()
	CMesh(CarID)=ode\mesh
	ScaleMesh ode\mesh,1.5,0.5,2
	RotateMesh ode\mesh,0,0,0
	PositionMesh ode\mesh,0,0,0
	If CarID=1
		EntityColor ode\mesh,40,80,255
		Else
		EntityColor ode\mesh,180,40,180
		End If
	EntityAlpha ode\mesh,1

	; ### Create wheels

	For count=1 To 4
		ode.ODEGeom=New ODEGeom
		ode\body=dBodyCreate(World)
		Wheel(CarID,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(CarID,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(CarID,1),(CarID*10)-2,CarStartY-0.5,+2)
	dBodySetPosition(Wheel(CarID,2),(CarID*10)+2,CarStartY-0.5,+2)
	dBodySetPosition(Wheel(CarID,3),(CarID*10)-2,CarStartY-0.5,-2)
	dBodySetPosition(Wheel(CarID,4),(CarID*10)+2,CarStartY-0.5,-2)

Next

; ### 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 capsules=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=dCreateCapsule(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(1))
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()

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

; ### 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(Space,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(Space,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

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

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,50,"Force Car 1:"+Force(1)
	Text 0,65,"Force Car 2:"+Force(2)
	Text 0,80,"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 CarID=1 To 2
	For count=1 To 4
		Joint(CarID,count)=dJointCreateHinge2(World,0)
		dJointAttach(Joint(CarID,count),Car(CarID),Wheel(CarID,count))
		dJointSetHinge2Anchor(Joint(CarID,count),dBodyGetPositionX(Wheel(CarID,count)),dBodyGetPositionY(Wheel(CarID,count)),dBodyGetPositionZ(Wheel(CarID,count)))
		dJointSetHinge2Axis1(Joint(CarID,count),0,1,0)
		dJointSetHinge2Axis2(Joint(CarID,count),-1,0,0)
		dJointSetHinge2Param(Joint(CarID,count),dParamSuspensionERP,0.8)
		dJointSetHinge2Param(Joint(CarID,count),dParamSuspensionCFM,SuspensionHS)
		If count>2
			dJointSetHinge2Param(Joint(CarID,count),dParamLoStop,0)
			dJointSetHinge2Param(Joint(CarID,count),dParamHiStop,0)
			End If
	Next
Force(CarID)=0
Next

End Function

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

Function UpdateKeys()

; ### Player Control For Car 1

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

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

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

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

If KeyHit(57)=1
	Force(1)=0
	dBodySetRotation(Car(1),dGeomGetPitch#(CGeom(1)),dGeomGetYaw#(CGeom(1)),0)
	End If

; ### Simple AI For Car 2

If ControlTimer>100
	SeedRnd MilliSecs()
	AIKey=Rnd(100)

	If AIKey<40
		Force(2)=Force(2)+0.8
		If Force(2)>10 Then Force(2)=10
		End If

	If AIKey=>40 Then Force(2)=Force(2)*0.99

	ControlTimer=0
	End If

If SteeringTimer>100
	SeedRnd MilliSecs()
	AIKey=Rnd(100)

	Steer(2)=0
	If AIKey<30 Then Steer(2)=0.5
	If AIKey>70 Then Steer(2)=-0.5

	SteeringTimer=0
	End If

ControlTimer=ControlTimer+1
SteeringTimer=SteeringTimer+1

End Function

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

Function UpdateCar()

For CarID=1 To 2
	For count=1 To 4
		dBodyEnable(Wheel(CarID,count))
	Next

	dBodyEnable(Car(CarID))

	For count=1 To 4
		dJointSetHinge2Param(Joint(CarID,count),dParamVel2,Force(CarID))
		dJointSetHinge2Param(Joint(CarID,count),dParamFMax2,Torque)
	Next

	For count=1 To 2
		angle#=Steer(CarID)-dJointGetHinge2Angle1(Joint(CarID,count))
		dJointSetHinge2Param(Joint(CarID,count),dParamVel,angle)
		dJointSetHinge2Param(Joint(CarID,count),dParamFMax,400)
	Next
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(1)

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

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