jv-ode more than one car

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

hi...
i learning use the jv-ode...

i make modifications from demo, trying to put two cars...

i can create the secound car... but i dont understand how works the keyboard control, with the force variable... how i apply to the secound car?...

each car is a type?... what type is ?

there is an example show this?, more than one car in jv-ode?

sorry, for my english...

Saludos..

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

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


hey, thanks VIP3R!!...

this is very helpfull!..
thanks!!! :)

nice demo vip3r :O)

Thanks both, you're welcome :)

Cheers viper, this is fantastic timing - I am just about to embark on the path of two vehicle control, on different computers but the logic will be the same within the code. Now I may add a 3rd truck - a computer AI truck that you have to 'race' to the respective end zones, ambitious but why not.......