JV-ODE Physics Thread 3

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

Here's a multimesh example I created a month ago using TED to create the landscape, if your interested in seeing it run with media email me.

I believe the JV/ODE demos include multispace examples too.

JV/ODE
http://www.devcode.co.uk/jv-ode.html

TED
http://www.d-grafix.com/softwareted.html#SCR

; ###################################################################################################
;                             JV-ODE Mars Terrain Demo                              
;                            Code by Wayne Gray , Jim Williams (VIP3R)                              
;                             This code is free, use as you wish.
; ###################################################################################################

AppTitle "ODE MARS Terrain Demo"

Include "JV-ODE.bb"

Graphics3D 800,600,0,2
;Graphics3D 1024,768,32,1
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=40

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 TriSpace=dHashSpaceCreate(space)
Global ContactGroup=dJointGroupCreate(0)

dWorldSetAutoDisableFlag(World,1)

dWorldSetERP(World,WorldERP)

dContactSetMode(dContactSlip1)
dContactSetMu(WorldFriction)

; Set Initial World
Global Planet$="Earth"
Global gx=1
dWorldSetGravity(World,0,-0.98,0)


; ### 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(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()
   dMassSetSphere(mass,1,0.7)
   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 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),44,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

; ### 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,200

Text 0,0,"Loading.. please wait"
Flip

;--------------------------------------------------------------
;load terrain
;--------------------------------------------------------------
Dim map(8,8)
Dim Tm(8,8)
Dim lm(8,8)

dir$="."

For b=1 To 8
   For a=1 To 8
      map(a,b)= LoadMesh(dir+"mars("+a+","+b+").b3d")
      UpdateNormals map(a,b)
      PositionEntity map(a,b),(a-1)*200,0,(b-1)*200
      ; Load ODE Trimeshes into trispace
      tm(a,b)=CreateTriMesh(trispace,map(a,b))
      dGeomSetPosition(tm(a,b),(a-1)*200,0,(b-1)*200)
      dGeomSetRotation(tm(a,b),0,0,0)
   Next
Next
; Tell the trispaces not to collide with each other.
dSetInternalSpaceCollideMode(0)

;--------------------------------------------------------------
;load &apply lm to tex layer 1
;--------------------------------------------------------------
For b=1 To 8
   For a=1 To 8
      lm(a,b) = LoadTexture(dir+"mars("+a+","+b+")_lm.bmp")
      EntityTexture map(a,b),lm(a,b),0,1
      EntityFX map(a,b),1
   Next
Next   
   
; ###################################################################################################

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 640,0,"A - Accelerate"
   Text 640,15,"Z - Brake/Reverse"
   Text 640,30,"Arrows - Steering"
   Text 640,45,"Space - Reset Car"
   Text 640,60,"P - Planet="+Planet

   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

; P - Planet
If KeyHit(25) Then
   gx=gx+1
   If gx>4 Then gx=1
   Select gx
     Case 1
      Planet="Earth "
      dWorldSetGravity(World,0,-1.0,0)
   
     Case 2
      Planet="Mars"
      dWorldSetGravity(World,0,-.33333,0)

     Case 3
      Planet="Moon"
      dWorldSetGravity(World,0,-.16666,0)
      
     Case 4
      Planet="Space"
      dWorldSetGravity(World,0,0,0)
   End Select
   
EndIf

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*1.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

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