in previous PB versions this is impossible
now in PB55 it is possible:
tank = CreateTube( #PB_Any, 3, 2, 2,16,1)
tank = CreateEntity(#PB_Any, MeshID(tank), MaterialID(1), 0, 2.0, -4)
AddSubEntity(\Chassis, tank, #PB_Entity_StaticBody)
the meaning of the last line is: add the tank to the \chassis with a geometry referred to by #PB_Entity_StaticBody which it is in fact (here) a concave geometry in a dynamic context.
previously the concave geometry is possible only in a static context.
press space to fill the tank with cubes . note that if the car with its tank deteriorated you will see the tank penetrate the static ground, somehow the collision disabled between the same objects having static type. but you can change the ground (line 97) from
CreateEntityBody(0, #PB_Entity_PlaneBody, 0, 0, 1) to
CreateEntityBody(0, #PB_Entity_BoxBody, 0, 0, 1)
to prevent sinking of the tank
there are several maneuvers
change the camera viewpoint by pressing ' V '
fill the tank with cubes by pressing 'Space' , and enjoy driving with your very heavy load
Code: Select all
;
; ------------------------------------------------------------
;
; PureBasic - CreateVehicle
;
; (c) Fantaisie Software
;
; ------------------------------------------------------------
;
IncludeFile #PB_Compiler_Home + "examples/3d/Screen3DRequester.pb"
#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]
EngineBrake.f
EngineForce.f
Steering.f
SteeringLeft.i
SteeringRight.i
EndStructure
Global Recul = #False
Global MaxEngineForce.f = 2000.0
Global MaxEngineBrake.f = 150.0
Global SteeringIncrement.f = 0.5
Global SteeringClamp.f = 27
Global WheelRadius.f = 0.5;
Global WheelWidth.f = 0.4 ;
Global SuspensionStiffness.f = 20.0
Global SuspensionDamping.f = 3.3
Global SuspensionCompression.f = 4.4
Global MaxSuspensionTravelCm.f = 500.0;
Global FrictionSlip.f = 20
Global RollInfluence.f = 0.3
Global SuspensionRestLength.f = 0.6;
Global Vehicle.s_Vehicle
#CUBE_HALF_EXTENTS = 1
Declare BuildVehicle(*Vehicle.s_Vehicle)
Declare HandleVehicle()
Declare ControlVehicle(elapsedTime.f)
Declare.f Interpolation(x1.f, x2.f, percent.f)
If InitEngine3D()
InitSprite()
InitKeyboard()
InitMouse()
If Screen3DRequester()
Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Textures/", #PB_3DArchive_FileSystem)
Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Packs/desert.zip", #PB_3DArchive_Zip)
Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Scripts" , #PB_3DArchive_FileSystem)
Parse3DScripts()
WorldShadows(#PB_Shadow_Modulative, -1, RGB(105, 105, 105))
;- Material
;
CreateMaterial(0, LoadTexture(0, "Wood.jpg"))
GetScriptMaterial(1, "SphereMap/SphereMappedRustySteel")
MaterialCullingMode(1, #PB_Material_NoCulling)
CreateMaterial(2, LoadTexture(2, "Dirt.jpg"))
ScaleMaterial(2,0.05,0.05)
GetScriptMaterial(3, "Scene/GroundBlend")
;-Ground
;
CreatePlane(0, 500, 500, 5, 5, 5, 5)
CreateEntity(0,MeshID(0),MaterialID(2))
EntityRenderMode(0, 0)
CreateEntityBody(0, #PB_Entity_PlaneBody, 0, 0, 1)
;CreateEntityBody(0, #PB_Entity_BoxBody, 0, 0, 1)
;#PB_Entity_HasContactResponse
;-Walls
;
CreateCube(1, 1)
CreateEntity(1,MeshID(1),MaterialID(2),0,1, 250)
ScaleEntity(1,500,2,0.5)
CreateEntityBody(1, #PB_Entity_PlaneBody, 0, 0, 1,-1,-1,-1, 0,0,-1)
CreateEntity(2,MeshID(1),MaterialID(2),0,1, -250)
ScaleEntity(2,500,2,0.5)
CreateEntityBody(2, #PB_Entity_PlaneBody, 0, 0, 1,-1,-1,-1, 0,0,1)
CreateEntity(3,MeshID(1),MaterialID(2),250,1, 0)
ScaleEntity(3,0.5,2,500)
CreateEntityBody(3, #PB_Entity_PlaneBody, 0, 0, 1,-1,-1,-1, -1,0,0)
CreateEntity(4,MeshID(1),MaterialID(2),-250,1, 0)
ScaleEntity(4,0.5,2,500)
CreateEntityBody(4, #PB_Entity_PlaneBody, 0, 0, 1,-1,-1,-1, 1,0,0)
CylinderMEsh = CreateCylinder(#PB_Any, 0.5, 2)
For i=-250 To 250 Step 30
Cylinder = CreateEntity(#PB_Any,MeshID(CylinderMEsh),MaterialID(1), 0, 1, i)
CreateEntityBody(Cylinder, #PB_Entity_CylinderBody, 0, 0, 1)
Next
;- Light
;
CreateLight(0 ,RGB(190, 190, 190), 400, 120, 100,#PB_Light_Directional)
SetLightColor(0, #PB_Light_SpecularColor, RGB(255*0.4, 255*0.4,255*0.4))
LightDirection(0 ,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, 500, 80, #PB_Absolute)
; SkyBox
;
SkyBox("desert07.jpg")
;-
BuildVehicle(@Vehicle)
;-Main
Global ball = CreateCube(#PB_Any, 0.5)
SetWindowTitle(0, "PureBasic-3D Demos ...'V': toggle view ...'Space' drop cubes")
Global viewnormal = 1
Repeat
Screen3DEvents()
ExamineMouse()
ExamineKeyboard()
HandleVehicle()
ControlVehicle(ElapsedTime/20)
If KeyboardPushed(#PB_Key_Space) ; fill the tank with cubes
i+1
CreateEntity(i+500, MeshID(ball), MaterialID(2), EntityX(Vehicle\Chassis), EntityY(Vehicle\Chassis)+Random(20,6), EntityZ(Vehicle\Chassis)-4)
CreateEntityBody(i+500, #PB_Entity_ConvexHullBody, 10,0.5,1)
EndIf
If KeyboardReleased(#PB_Key_V)
viewnormal ! 1
EndIf
If viewnormal
CameraFollow(0, EntityID(Vehicle\Chassis),130, 6.5, 15, 0.1, 0.1)
Else
CameraFollow(0, EntityID(Vehicle\Chassis),180, 6.5, 15, 0.1, 0.1)
EndIf
ElapsedTime = RenderWorld()
FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape)
End
EndIf
Else
MessageRequester("Error","Can't initialize engine3D")
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 BuildVehicle(*Vehicle.s_Vehicle)
Protected.VECTOR3 connectionPointCS0; wheelDirectionCS0,wheelAxleCS,
With *Vehicle
\SteeringLeft = #False
\SteeringRight = #False
\EngineForce = 0
\Steering = 0
;- >>> create vehicle <<<<<
connectionHeight.f = 0.6
ChassisMesh = CreateCube(#PB_Any, 2)
ChassisEntity = CreateEntity(#PB_Any, MeshID(chassisMesh), MaterialID(3), 0, 1, 0)
ScaleEntity(ChassisEntity, 0.8, 0.7, 2)
;CreateTube(#Mesh, OuterRadius.f, InnerRadius.f, Height.f [, NbBaseSegments, NbHeightSegments)
tank = CreateTube( #PB_Any, 3, 2, 2,16,1)
tank = CreateEntity(#PB_Any, MeshID(tank), MaterialID(1), 0, 2.0, -4)
TankBottom = CreateEntity(#PB_Any, MeshID(CreateSphere(#PB_Any,1)), MaterialID(2), 0, 2, -4)
ScaleEntity(TankBottom, 2,0.1,2)
\Chassis = CreateVehicle(#PB_Any)
AddSubEntity(\Chassis, ChassisEntity, #PB_Entity_BoxBody)
AddSubEntity(\Chassis, tank, #PB_Entity_StaticBody)
AddSubEntity(\Chassis, TankBottom, #PB_Entity_ConvexHullBody)
EntityRenderMode(\Chassis, #PB_Entity_CastShadow)
CreateVehicleBody(\Chassis, 700, 0.3, 0.8,suspensionStiffness, suspensionCompression, suspensionDamping, maxSuspensionTravelCm, frictionSlip)
MoveEntity(\Chassis, 0, 3, 0,#PB_Absolute)
DisableDebugger
SetEntityAttribute(\Chassis, 27, 0.0)
SetEntityAttribute(\Chassis, 28, 0.0)
EnableDebugger
Wheel = CreateSphere(#PB_Any, WheelRadius)
For i = 0 To 3
\Wheels[i] = CreateEntity(#PB_Any, MeshID(Wheel), #PB_Material_None)
ScaleEntity(\Wheels[i], WheelWidth,1,1)
Next
;-WheelSteerable and WheelsEngine
VECTOR3(connectionPointCS0, #CUBE_HALF_EXTENTS-(0.2*WheelWidth), connectionHeight,2*#CUBE_HALF_EXTENTS-WheelRadius)
AddVehicleWheel(\Chassis, \Wheels[0],
connectionPointCS0\x, connectionPointCS0\y,connectionPointCS0\z,
-1, 0,0, SuspensionRestLength, WheelRadius, #True, RollInfluence)
VECTOR3(connectionPointCS0, -#CUBE_HALF_EXTENTS+(0.2*WheelWidth), connectionHeight, 2*#CUBE_HALF_EXTENTS-WheelRadius)
AddVehicleWheel(\Chassis, \Wheels[1],
connectionPointCS0\x, connectionPointCS0\y,connectionPointCS0\z,
-1, 0,0, SuspensionRestLength, WheelRadius, #True, RollInfluence)
VECTOR3(connectionPointCS0, -#CUBE_HALF_EXTENTS+(0.2*WheelWidth), connectionHeight, -2*#CUBE_HALF_EXTENTS+WheelRadius);
AddVehicleWheel(\Chassis, \Wheels[2],
connectionPointCS0\x, connectionPointCS0\y,connectionPointCS0\z,
-1, 0,0, SuspensionRestLength, WheelRadius, #False, RollInfluence)
VECTOR3(connectionPointCS0, #CUBE_HALF_EXTENTS-(0.2*WheelWidth), connectionHeight, -2*#CUBE_HALF_EXTENTS+WheelRadius);
AddVehicleWheel(\Chassis, \Wheels[3],
connectionPointCS0\x, connectionPointCS0\y,connectionPointCS0\z,
-1, 0,0, SuspensionRestLength, WheelRadius, #False, RollInfluence)
EndWith
EndProcedure
Procedure HandleVehicle()
If KeyboardPushed(#PB_Key_Left)
Vehicle\SteeringLeft = #True
Vehicle\SteeringRight = #False
ElseIf KeyboardPushed(#PB_Key_Right)
Vehicle\SteeringRight = #True
Vehicle\SteeringLeft = #False
Else
Vehicle\SteeringRight = #False
Vehicle\SteeringLeft = #False
EndIf
If KeyboardPushed(#PB_Key_Down)
If GetEntityAttribute(Vehicle\Chassis, #PB_Entity_LinearVelocity)< 0.4
Recul = #True
EndIf
If Recul
Vehicle\EngineForce = -MaxEngineForce
Vehicle\EngineBrake = 0
Else
Vehicle\EngineForce = 0
Vehicle\EngineBrake = MaxEngineBrake
EndIf
ElseIf KeyboardPushed(#PB_Key_Up)
Vehicle\EngineForce = MaxEngineForce
Vehicle\EngineBrake = 0
Else
Vehicle\EngineBrake = MaxEngineForce/ 100
Vehicle\EngineForce = 0
Recul = #False
EndIf
EndProcedure
Procedure ControlVehicle(elapsedTime.f)
; apply engine Force on relevant wheels
For i = 0 To 1
ApplyVehicleBrake(Vehicle\Chassis, i, Vehicle\EngineBrake)
ApplyVehicleForce(Vehicle\Chassis, i, Vehicle\EngineForce)
Next
If (Vehicle\SteeringLeft)
Vehicle\Steering + SteeringIncrement*elapsedTime
If (Vehicle\Steering > SteeringClamp)
Vehicle\Steering = SteeringClamp
EndIf
ElseIf (Vehicle\SteeringRight)
Vehicle\Steering - SteeringIncrement*elapsedTime
If (Vehicle\Steering < -SteeringClamp)
Vehicle\Steering = -SteeringClamp
EndIf
Else
Vehicle\Steering = Interpolation(Vehicle\Steering, 0, 0.05)
EndIf
; apply Steering on relevant wheels
For i = 0 To 1
ApplyVehicleSteering(Vehicle\Chassis, i, Vehicle\Steering)
Next
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


