PB5.70 Vehicle contact

Everything related to 3D programming
User avatar
Comtois
Addict
Addict
Posts: 1429
Joined: Tue Aug 19, 2003 11:36 am
Location: Doubs - France

PB5.70 Vehicle contact

Post by Comtois »

An exemple using new constants

Code: Select all

; It can take few minutes to build all terrains (it will be more faster after saving it)
MessageRequester("Warning !", "It can take a few minutes to build all terrains...", 0)
IncludeFile #PB_Compiler_Home + "examples/3d/Screen3DRequester.pb"

#CameraSpeed = 2

#CameraSpeed = 2
Global.f KeyX, KeyY, MouseX, MouseY, ElapsedTime

Structure Vector3
  x.f
  y.f
  z.f
EndStructure

Macro VECTOR3(V, a, b, c)
  V\x = a
  V\y = b
  V\z = c
EndMacro

Structure s_Vehicle
  Chassis.i
  Wheels.i[4]
  
  WheelsEngine.i[4]
  WheelsEngineCount.i
  WheelsSteerable.i[4]
  WheelsSteerableCount.i
  
  EngineBrake.f
  EngineForce.f
  Steering.f
  
  SteeringLeft.i
  SteeringRight.i
EndStructure

Global MaxEngineForce.f = 3000.0
Global MaxEngineBrake.f = 100.0

Global SteeringIncrement.f = 0.5
Global SteeringClamp.f = 23       

Global WheelRadius.f = 0.50;
Global WheelWidth.f = 0.4  ;

Global SuspensionStiffness.f = 25.0
Global SuspensionDamping.f =  0.4 * 2.0 * Sqr(suspensionStiffness)
Global SuspensionCompression.f =  0.2 * 2.0 * Sqr(suspensionStiffness)
Global MaxSuspensionTravelCm.f = 400.0;
Global FrictionSlip.f = 1000     

Global RollInfluence.f = 0.5
Global SuspensionRestLength.f = 0.6;
                                   ;


Global VECTOR3(CameraStart.Vector3, 0, 25, 0)

Global VECTOR3(CarPosition.Vector3, 15, 3, -15)

Global Vehicle.s_Vehicle


#CUBE_HALF_EXTENTS = 1


Declare BuildVehicle(*Vehicle.s_Vehicle)
Declare HandleVehicle()
Declare ControlVehicle(elapsedTime.f)
Declare InitBlendMaps()
Declare.f Interpolation(x1.f, x2.f, percent.f)
Declare contact(*Vehicle.s_Vehicle)

; OpenGL needs to have CG enabled to work (Linux and OS X have OpenGL by default)
;
CompilerIf #PB_Compiler_OS <> #PB_OS_Windows Or Subsystem("OpenGL")
  Flags = #PB_Engine3D_EnableCG
CompilerEndIf

If InitEngine3D(Flags)
  
  InitSprite()
  InitKeyboard()
  InitMouse()
  
  If Screen3DRequester()
    Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Textures/", #PB_3DArchive_FileSystem)
    Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Textures/nvidia", #PB_3DArchive_FileSystem)
    Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Packs/desert.zip", #PB_3DArchive_Zip)
    Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/fonts", #PB_3DArchive_FileSystem)
    Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Models", #PB_3DArchive_FileSystem)
    Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Scripts", #PB_3DArchive_FileSystem)
    
    Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Particles"           , #PB_3DArchive_FileSystem)
    Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/OPE/material_scripts", #PB_3DArchive_FileSystem)
    Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/OPE/textures"        , #PB_3DArchive_FileSystem)
    Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/OPE/particle_scripts", #PB_3DArchive_FileSystem)
    Parse3DScripts()
    
    
    WorldShadows(#PB_Shadow_Modulative, -1, RGB(105, 105, 105))
    ;WorldDebug(#PB_World_DebugBody)
    ;- Light
    ;
    light = CreateLight(#PB_Any ,RGB(190, 190, 190), 400, 120, 100,#PB_Light_Directional)
    SetLightColor(light, #PB_Light_SpecularColor, RGB(255*0.4, 255*0.4,255*0.4))
    LightDirection(light ,0.55, -0.3, -0.75)
    AmbientColor(RGB(255*0.2, 255*0.2,255*0.2))
    
    ;- Camera
    ;
    CreateCamera(0, 0, 0, 100, 100)
    MoveCamera(0,  800, 400, 80, #PB_Absolute)
    CameraBackColor(0, RGB(5, 5, 10))
    
    
    ;- Terrain definition
    SetupTerrains(LightID(Light), 600, #PB_Terrain_NormalMapping)
    ; initialize terrain
    CreateTerrain(0, 513, 800, 20, 3, "TerrainGroup", "dat")
    ; set all texture will be use when terrrain will be constructed
    AddTerrainTexture(0,  0, 100, "dirt_grayrocky_diffusespecular.jpg",  "dirt_grayrocky_normalheight.jpg")
    AddTerrainTexture(0,  1,  30, "grass_green-01_diffusespecular.jpg", "grass_green-01_normalheight.jpg")
    AddTerrainTexture(0,  2, 200, "growth_weirdfungus-03_diffusespecular.jpg", "growth_weirdfungus-03_normalheight.jpg")
    
    ; Build terrains
    Imported = DefineTerrainTile(0, 0, 0, "terrain513.png", 0, 0)
    BuildTerrain(0)
    
    If imported = #True
      InitBlendMaps()
      UpdateTerrain(0)
      
      ; If enabled, it will save the terrain as a (big) cache for a faster load next time the program is executed
      ; SaveTerrain(0, #False)
    EndIf
    ; enable shadow terrain
    TerrainRenderMode(0, 0)
    
    
    ;Add Physic
    CreateTerrainBody(0, 0.1, 0.0)
    
    ; SkyBox
    ;
    SkyBox("desert07.jpg")
    
    ; Particle
    ;
    ParticleTexture = LoadTexture(#PB_Any, "flare.png")
    ParticleMaterial = CreateMaterial(#PB_Any, TextureID(ParticleTexture))
    DisableMaterialLighting(ParticleMaterial, 1)
    MaterialBlendingMode(ParticleMaterial, #PB_Material_Add)
    
    For i=0 To 3
      CreateParticleEmitter(i, 0, 0, 0, #PB_Particle_Point)
      ParticleMaterial    (i, MaterialID(ParticleMaterial))
      ParticleSize        (i, 0.5, 0.5)
      ParticleEmissionRate(i, 50)
      ParticleColorRange(i, RGB(0,50,200), RGB(0,50,200))
      ParticleTimeToLive  (i, 1, 1)
      ParticleVelocity(i, #PB_Particle_Velocity,1)
    Next
    
    
    
    BuildVehicle(@Vehicle)
    
    Repeat
      Screen3DEvents()
      
      ExamineMouse()
      ExamineKeyboard()
      
      
      handleVehicle()
      ControlVehicle(ElapsedTime/20)
      contact(@Vehicle)
      CameraFollow(0, EntityID(Vehicle\Chassis),180, TerrainHeight(0,CameraX(0),CameraZ(0))+2.5, 7, 0.08, 0.08)
      
      ElapsedTime = RenderWorld()
      FlipBuffers()
      
    Until KeyboardPushed(#PB_Key_Escape)   
    
    End
    
  EndIf
Else
  CompilerIf #PB_Compiler_OS <> #PB_OS_Windows Or Subsystem("OpenGL")
    ;
    ; Terrain on Linux/OSX and Windows with OpenGL needs CG toolkit from nvidia
    ; It can be freely downloaded and installed from this site: https://developer.nvidia.com/cg-toolkit-download
    ;
    MessageRequester("Error","Can't initialize engine3D (Please ensures than CG Toolkit from nvidia is correcly installed)")
  CompilerElse
    MessageRequester("Error","Can't initialize engine3D")
  CompilerEndIf
EndIf

Procedure Clamp(*var.float, min.f, max.f)
  If *var\f < min
    *var\f = min
  ElseIf *var\f > max
    *var\f = max
  EndIf
EndProcedure

Procedure InitBlendMaps()
  minHeight1.f = 70
  fadeDist1.f = 40
  minHeight2.f = 70
  fadeDist2.f = 15   
  ty = 0
  tx = 0
  Size = TerrainTileLayerMapSize(0, tx, ty)
  For y = 0 To Size-1
    For x = 0 To Size-1
      Height.f = TerrainTileHeightAtPosition(0, tx, ty, 1, x, y)
      
      val.f = (Height - minHeight1) / fadeDist1
      Clamp(@val, 0, 1)
      SetTerrainTileLayerBlend(0, tx, ty, 1, x, y, val)
      
      val.f = (Height - minHeight2) / fadeDist2
      Clamp(@val, 0, 1)
      SetTerrainTileLayerBlend(0, tx, ty, 2, x, y, val)
    Next
  Next
  UpdateTerrainTileLayerBlend(0, tx, ty, 1)
  UpdateTerrainTileLayerBlend(0, tx, ty, 2)
  
EndProcedure

Procedure contact(*Vehicle.s_Vehicle)
  d=3
  
  ;Forward Vector
  xe.f = EntityX(*Vehicle\Chassis)
  ye.f = EntityY(*Vehicle\Chassis)
  ze.f = EntityZ(*Vehicle\Chassis)
  xf.f = -GetVehicleAttribute(*Vehicle\Chassis, #PB_Vehicle_ForwardVectorX,0)
  yf.f = -GetVehicleAttribute(*Vehicle\Chassis, #PB_Vehicle_ForwardVectorY,0)
  zf.f = -GetVehicleAttribute(*Vehicle\Chassis, #PB_Vehicle_ForwardVectorZ,0)
  ;CreateLine3D(15, xe,ye,ze, RGB(255,255,0),xe+xf*d,ye+yf*d,ze+zf*d, RGB(255,255,0))
  
  ;Normal at contact point
  For i=0 To 3
    If GetVehicleAttribute(*Vehicle\Chassis, #PB_Vehicle_IsInContact, i)
      x.f = GetVehicleAttribute(*Vehicle\Chassis, #PB_Vehicle_ContactPointX, i)
      y.f = GetVehicleAttribute(*Vehicle\Chassis, #PB_Vehicle_ContactPointY, i)
      z.f = GetVehicleAttribute(*Vehicle\Chassis, #PB_Vehicle_ContactPointZ, i)
      xn.f = GetVehicleAttribute(*Vehicle\Chassis, #PB_Vehicle_ContactPointNormalX, i)
      yn.f = GetVehicleAttribute(*Vehicle\Chassis, #PB_Vehicle_ContactPointNormalY, i)
      zn.f = GetVehicleAttribute(*Vehicle\Chassis, #PB_Vehicle_ContactPointNormalZ, i)     
      ;CreateLine3D(10+i, x,y,z, RGB(0,255,0),x+xn*d,y+yn*d,z+zn*d, RGB(0,255,0))   
    Else
      If IsMesh(10+i)
        FreeMesh(10+i)
      EndIf
    EndIf
  Next
  
  ;Particle
  
  For i=0 To 3
    If GetVehicleAttribute(*Vehicle\Chassis, #PB_Vehicle_IsInContact, i)
      x.f = GetVehicleAttribute(*Vehicle\Chassis, #PB_Vehicle_ContactPointX, i)
      y.f = GetVehicleAttribute(*Vehicle\Chassis, #PB_Vehicle_ContactPointY, i)
      z.f = GetVehicleAttribute(*Vehicle\Chassis, #PB_Vehicle_ContactPointZ, i)
      HideParticleEmitter(i, 0)
      ParticleEmitterDirection(i, xf, yf, zf)
      MoveParticleEmitter(i, x, y+0.25, z, #PB_Absolute)
    Else
      HideParticleEmitter(i, 1)
    EndIf
  Next
  
  ;Speed
  t$ = Str(GetVehicleAttribute(*Vehicle\Chassis, #PB_Vehicle_CurrentSpeed,0))
  CreateText3D(0, t$ + " km/h")
  Text3DColor(0, RGBA(255, 0, 0, 255))
  Text3DAlignment(0, #PB_Text3D_HorizontallyCentered)
  AttachEntityObject(*Vehicle\Chassis, "", Text3DID(0))
  MoveText3D(0, -0.4, 2.3, 0)
  ScaleText3D(0, 0.5, 0.5, 0.5)
  
  
  CreateText3D(1, t$ + " km/h")
  Text3DColor(1, RGBA(255, 255, 0, 255))
  Text3DAlignment(1, #PB_Text3D_HorizontallyCentered)
  AttachEntityObject(*Vehicle\Chassis, "", Text3DID(1))
  MoveText3D(1, -0.41, 2.31, 0)
  ScaleText3D(1, 0.5, 0.5, 0.5)
  
EndProcedure

Procedure BuildVehicle(*Vehicle.s_Vehicle)
  Protected.VECTOR3 wheelDirectionCS0,wheelAxleCS,connectionPointCS0
  
  With *Vehicle
    ;reset
    For i = 0 To 3
      
      \WheelsEngine[i] = 0
      \WheelsSteerable[i] = 0
    Next
    \WheelsEngineCount = 2
    \WheelsEngine[0] = 0
    \WheelsEngine[1] = 1
    \WheelsEngine[2] = 2
    \WheelsEngine[3] = 3
    
    \WheelsSteerableCount = 2
    \WheelsSteerable[0] = 0
    \WheelsSteerable[1] = 1
    
    \SteeringLeft = #False
    \SteeringRight = #False
    
    \EngineForce = 0
    \Steering = 0
    
    
    ;- >>> create vehicle  <<<<<
    
    connectionHeight.f = 0.7
    
    ChassisMesh = LoadMesh(#PB_Any, "chassis.mesh")
    ChassisEntity = CreateEntity(#PB_Any, MeshID(chassisMesh), #PB_Material_None, 0, 1.0, 0)
    
    \Chassis = CreateVehicle(#PB_Any)
    AddSubEntity(\Chassis, ChassisEntity, #PB_Entity_BoxBody, 0, 0, 0, 0, 1.0, 0.75, 2.1)
    
    EntityRenderMode(\Chassis, #PB_Entity_CastShadow )
    CreateVehicleBody(\Chassis, 700, 0.3, 0.8,suspensionStiffness, suspensionCompression, suspensionDamping, maxSuspensionTravelCm, frictionSlip)
    
    MoveEntity(\Chassis, 0, 15, 0,#PB_Absolute)
    
    wheelAxleCS\x       = -1
    wheelAxleCS\y       = 0
    wheelAxleCS\z       = 0
    
    Wheel = LoadMesh(#PB_Any, "wheel.mesh")
    For i = 0 To 3
      \Wheels[i] = CreateEntity(#PB_Any, MeshID(Wheel), #PB_Material_None,0,0,0, 32)
    Next
    
    isFrontWheel = #True
    
    ;-WheelSteerable and WheelsEngine
    VECTOR3(connectionPointCS0, #CUBE_HALF_EXTENTS-(0.3*WheelWidth), connectionHeight,2*#CUBE_HALF_EXTENTS-WheelRadius)
    AddVehicleWheel(\Chassis, \Wheels[0],
                    connectionPointCS0\x, connectionPointCS0\y,connectionPointCS0\z,
                    wheelAxleCS\x, wheelAxleCS\y,wheelAxleCS\z,
                    SuspensionRestLength,
                    WheelRadius,
                    isFrontWheel,
                    RollInfluence)
    
    ;-WheelSteerable and WheelsEngine
    VECTOR3(connectionPointCS0, -#CUBE_HALF_EXTENTS+(0.3*WheelWidth), connectionHeight, 2*#CUBE_HALF_EXTENTS-WheelRadius)
    AddVehicleWheel(\Chassis, \Wheels[1],
                    connectionPointCS0\x, connectionPointCS0\y,connectionPointCS0\z,
                    wheelAxleCS\x, wheelAxleCS\y,wheelAxleCS\z,
                    SuspensionRestLength,
                    WheelRadius,
                    isFrontWheel,
                    RollInfluence)
    
    isFrontWheel = #False
    
    VECTOR3(connectionPointCS0, -#CUBE_HALF_EXTENTS+(0.3*WheelWidth), connectionHeight, -2*#CUBE_HALF_EXTENTS+WheelRadius);
    AddVehicleWheel(\Chassis, \Wheels[2],
                    connectionPointCS0\x, connectionPointCS0\y,connectionPointCS0\z,
                    wheelAxleCS\x, wheelAxleCS\y,wheelAxleCS\z,
                    SuspensionRestLength,
                    WheelRadius,
                    isFrontWheel,
                    RollInfluence)
    
    
    VECTOR3(connectionPointCS0, #CUBE_HALF_EXTENTS-(0.3*WheelWidth), connectionHeight, -2*#CUBE_HALF_EXTENTS+WheelRadius);
    AddVehicleWheel(\Chassis, \Wheels[3],
                    connectionPointCS0\x, connectionPointCS0\y,connectionPointCS0\z,
                    wheelAxleCS\x, wheelAxleCS\y,wheelAxleCS\z,
                    SuspensionRestLength,
                    WheelRadius,
                    isFrontWheel,
                    RollInfluence)
    
    For i= 0 To 3
      SetVehicleAttribute(\Chassis, #PB_Vehicle_MaxSuspensionForce, 4000, i)
    Next   
    
  EndWith
EndProcedure

Procedure HandleVehicle()
  With Vehicle
    
    
    If KeyboardPushed(#PB_Key_Left)
      \SteeringLeft = #True
      \SteeringRight = #False
    ElseIf KeyboardPushed(#PB_Key_Right)
      \SteeringRight = #True
      \SteeringLeft = #False
    Else
      \SteeringRight = #False
      \SteeringLeft = #False         
    EndIf
    
    
    If KeyboardPushed(#PB_Key_Down)
      \EngineForce = 0
      \EngineBrake = MaxEngineBrake
    ElseIf KeyboardPushed(#PB_Key_Up)
      \EngineForce = MaxEngineForce
      \EngineBrake = 0
    Else
      \EngineBrake = 0
      \EngineForce = 0
    EndIf
    
    
    ;  PBO_SetVehicleAttribute(\Chassis, #PB_Vehicle_RollInfluence, 2)
    
  EndWith
EndProcedure

Procedure ControlVehicle(elapsedTime.f)
  With Vehicle
    
    ; apply engine Force on relevant wheels
    For i = \WheelsEngine[0] To \WheelsEngine[0]+\WheelsEngineCount-1
      ApplyVehicleBrake(\Chassis, \WheelsEngine[i], \EngineBrake)
      ApplyVehicleForce(\Chassis, \WheelsEngine[i], \EngineForce)
    Next
    
    If (\SteeringLeft)
      
      \Steering + SteeringIncrement*elapsedTime
      If (\Steering > SteeringClamp)
        \Steering = SteeringClamp
      EndIf
      
    ElseIf (\SteeringRight)
      
      \Steering - SteeringIncrement*elapsedTime
      If (\Steering < -SteeringClamp)
        \Steering = -SteeringClamp
      EndIf
    Else
      \Steering = Interpolation(\Steering, 0, 0.05)
    EndIf
    
    ; apply Steering on relevant wheels
    
    For i = \WheelsSteerable[0] To \WheelsSteerable[0]+ \WheelsSteerableCount-1
      
      If (i < 2)
        ApplyVehicleSteering(\Chassis, \WheelsSteerable[i], \Steering)
      Else
        ApplyVehicleSteering(\Chassis, \WheelsSteerable[i], -\Steering)
      EndIf
    Next
    
  EndWith   
EndProcedure

Procedure.f Interpolation(x1.f, x2.f, percent.f)
  If percent<0
    percent=0
  EndIf
  If percent>1
    percent=1
  EndIf
  ProcedureReturn x1 + percent * (x2 - x1)
  
EndProcedure
Last edited by Comtois on Tue Dec 17, 2019 7:45 pm, edited 2 times in total.
Please correct my english
http://purebasic.developpez.com/
Dude
Addict
Addict
Posts: 1907
Joined: Mon Feb 16, 2015 2:49 pm

Re: PB5.70 Vehicle contact

Post by Dude »

Doesn't run on the x86 version... don't know if it's your code or a beta bug?

Code: Select all

[21:25:40] Waiting for executable to start...
[21:25:40] Executable type: Windows - x86  (32bit, Unicode)
[21:25:40] Executable started.
[21:25:46] [ERROR] Line: 164
[21:25:46] [ERROR] ParticleVelocity(): invalid value specified for parameter 'Mode'.
Fred
Administrator
Administrator
Posts: 16623
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: PB5.70 Vehicle contact

Post by Fred »

You can try with disabled debugger
Dude
Addict
Addict
Posts: 1907
Joined: Mon Feb 16, 2015 2:49 pm

Re: PB5.70 Vehicle contact

Post by Dude »

Ooooooh! :D
User avatar
Comtois
Addict
Addict
Posts: 1429
Joined: Tue Aug 19, 2003 11:36 am
Location: Doubs - France

Re: PB5.70 Vehicle contact

Post by Comtois »

Dude wrote:Doesn't run on the x86 version... don't know if it's your code or a beta bug?

Code: Select all

[21:25:40] Waiting for executable to start...
[21:25:40] Executable type: Windows - x86  (32bit, Unicode)
[21:25:40] Executable started.
[21:25:46] [ERROR] Line: 164
[21:25:46] [ERROR] ParticleVelocity(): invalid value specified for parameter 'Mode'.
oups

Code: Select all

    ParticleVelocity(i, 1, #PB_Particle_Velocity)
should be

Code: Select all

    ParticleVelocity(i, #PB_Particle_Velocity,1)
Please correct my english
http://purebasic.developpez.com/
User avatar
VB6_to_PBx
Enthusiast
Enthusiast
Posts: 617
Joined: Mon May 09, 2011 9:36 am

Re: PB5.70 Vehicle contact

Post by VB6_to_PBx »

Fred wrote:You can try with disabled debugger
with Win7 and 32-Bit PB5.70 Beta1

it does not Run with the Debugger disabled ... Mouse Cursor is locked in an invisible sectioned window until i press ESC button

with Debugger enabled , it runs very fast and great , no problems :)
 
PureBasic .... making tiny electrons do what you want !

"With every mistake we must surely be learning" - George Harrison
dige
Addict
Addict
Posts: 1247
Joined: Wed Apr 30, 2003 8:15 am
Location: Germany
Contact:

Re: PB5.70 Vehicle contact

Post by dige »

Impressive!
"Daddy, I'll run faster, then it is not so far..."
Torp
User
User
Posts: 82
Joined: Fri Apr 01, 2005 11:29 am

Re: PB5.70 Vehicle contact

Post by Torp »

Hello,

For me it crash at line 183 : "ElapsedTime = RenderWorld()" , invalid access memory. (crash also without debugger)
Post Reply