Tokamak Rally

Miscellaneous Forums/Blitz Showcase/Tokamak Rally

Ok, here it is...(messy & badly commented, the Sweenie way!)


Const FPS=90
Type vector
	Field x#
	Field y#
	Field z#
End Type
Global CProd.vector=New vector
Type csys
   Field cx#,cy#,cz#
   Field mx#,my#,sps
End Type

Graphics3D 800,600,0,2
SetBuffer BackBuffer()

camera = CreateCamera()
PositionEntity camera,10,8,-5

WireFrame False

TOKSIM_CreateSimulator(0,-9.0,0)
TOKSIM_SetMaterial 0,0.0,0.6 

ColBank=CreateBank(104*10)
TOKSIM_SetCInfoBank ColBank
TOKSIM_SetCollisionResponse -1,1,3 ; Impulse & Feedback 
TOKSIM_SetCollisionResponse -1,2,0 ; No Impulse Or Feedback 


tex = LoadTexture("track.bmp")
Terrain = LoadMesh("track.3ds")
ScaleMesh Terrain,25.0,25.0,25.0 
RotateMesh Terrain,-90,0,0
EntityTexture terrain,tex
MakeTokCollider(Terrain)

SeedRnd MilliSecs()  

Global Body_Mesh = LoadMesh("truck_body.b3d")
ScaleMesh Body_Mesh,0.3,0.3,0.3
PositionMesh Body_Mesh,0.0,-2.1,0.0
RotateMesh Body_Mesh,0,180,0

Global Body_RB = TOKRB_Create()
TOKRB_AddBox Body_RB,2.0,1.0,3.0
TOKRB_SetPosition Body_RB,0,5,0
TOKRB_SetMass Body_RB,1.0
TOKRB_SetBoxInertiaTensor Body_RB,2.0,1.0,3.0,1.0
ExtraWeight = TOKRB_Create()
TOKRB_SetCollisionID ExtraWeight,2
TOKRB_SetMass ExtraWeight,0.4
TOKRB_SetSphereInertiaTensor ExtraWeight,0.5,0.4 
TOKRB_SetPosition ExtraWeight,0,5,1.5
ConnJoint = TOKJOINT_Create(2,ExtraWeight,Body_RB)
TOKJOINT_SetType ConnJoint,1 
TOKJOINT_SetPositionAndRotationWorld ConnJoint,0,5.0,1.5,0,0,0 
TOKJOINT_Enable ConnJoint,True

Global RR_Spr_RB = TOKRB_Create()
TOKRB_AddSphere RR_Spr_RB,1.0
TOKRB_SetPosition RR_Spr_RB,1.2,3.0,-1.50
TOKRB_SetMass RR_Spr_RB,1.0
TOKRB_SetSphereInertiaTensor RR_Spr_RB,1.0,1.0
TOKRB_SetCollisionID RR_Spr_RB,1 
RR_SprJoint = TOKJOINT_Create(2,RR_Spr_RB,Body_RB)
TOKJOINT_SetType RR_SprJoint,4 ; Slidejoint
TOKJOINT_SetPositionAndRotationWorld RR_SprJoint,1.2,3.0,-1.50,0,0,0 
TOKJOINT_Enable RR_SprJoint,True

Global RL_Spr_RB = TOKRB_Create()
TOKRB_AddSphere RL_Spr_RB,1.0
TOKRB_SetPosition RL_Spr_RB,-1.2,3.0,-1.5
TOKRB_SetMass RL_Spr_RB,1.0
TOKRB_SetSphereInertiaTensor RL_Spr_RB,1.0,1.0
TOKRB_SetCollisionID RL_Spr_RB,1 
RL_SprJoint = TOKJOINT_Create(2,RL_Spr_RB,Body_RB)
TOKJOINT_SetType RL_SprJoint,4 ; Slidejoint
TOKJOINT_SetPositionAndRotationWorld RL_SprJoint,-1.2,3.0,-1.5,0,0,0 
TOKJOINT_Enable RL_SprJoint,True

Global FR_Spr_RB = TOKRB_Create()
TOKRB_AddSphere FR_Spr_RB,1.0
TOKRB_SetPosition FR_Spr_RB,1.2,3.0,1.65
TOKRB_SetMass FR_Spr_RB,1.0
TOKRB_SetSphereInertiaTensor FR_Spr_RB,1.0,1.0
TOKRB_SetCollisionID FR_Spr_RB,1 
FR_SprJoint = TOKJOINT_Create(2,FR_Spr_RB,Body_RB)
TOKJOINT_SetType FR_SprJoint,4 ; Slidejoint
TOKJOINT_SetPositionAndRotationWorld FR_SprJoint,1.2,3.0,1.65,0,0,0 
TOKJOINT_Enable FR_SprJoint,True

Global FL_Spr_RB = TOKRB_Create()
TOKRB_AddSphere FL_Spr_RB,1.0
TOKRB_SetPosition FL_Spr_RB,-1.2,3.0,1.65
TOKRB_SetMass FL_Spr_RB,1.0
TOKRB_SetSphereInertiaTensor FL_Spr_RB,1.0,1.0
TOKRB_SetCollisionID FL_Spr_RB,1 
FL_SprJoint = TOKJOINT_Create(2,FL_Spr_RB,Body_RB)
TOKJOINT_SetType FL_SprJoint,4 ; Slidejoint
TOKJOINT_SetPositionAndRotationWorld FL_SprJoint,-1.2,3.0,1.65,0,0,0 
TOKJOINT_Enable FL_SprJoint,True


FR_Wheel=LoadMesh("truck_wheel.b3d")
ScaleMesh FR_Wheel,0.3,0.3,0.3
FL_Wheel=LoadMesh("truck_wheel.b3d")
ScaleMesh FL_Wheel,0.3,0.3,0.3
RR_Wheel=LoadMesh("truck_wheel.b3d")
ScaleMesh RR_Wheel,0.3,0.3,0.3
RL_Wheel=LoadMesh("truck_wheel.b3d")
ScaleMesh RL_Wheel,0.3,0.3,0.3

CamPoint = TOKRB_Create()
TOKRB_SetMass CamPoint,1.0
TOKRB_SetSphereInertiaTensor FR_Spr_RB,1.0,1.0
TOKRB_SetLinearDamping CamPoint,0.01

Centerpivot = CreatePivot()

CamTargetPivot=CreatePivot()

Global speed#=0

GripFactor#=0.2

light=CreateLight()
LightColor light,128,128,128 
PositionEntity light,255,255,-255

PointEntity light,Centerpivot

period=1000/FPS
time=MilliSecs()-period
Global timestep#=1.5/FPS
; MainLoop
While Not KeyHit(1)

	Repeat
		elapsed=MilliSecs()-time
	Until elapsed

	ticks=elapsed/period
	tween#=Float(elapsed Mod period)/Float(period)

	For k=1 To ticks
		time=time+period
		If k=ticks Then CaptureWorld

		TOKSIM_Advance(1.5/FPS,1)


	UpdateWorld

    PlaceMesh Body_Mesh,Body_RB
	PositionEntity FR_Wheel,TOKRB_GetX#(FR_Spr_RB),TOKRB_GetY#(FR_Spr_RB),TOKRB_GetZ#(FR_Spr_RB)
	RotateEntity FR_Wheel,EntityPitch#(Body_Mesh),EntityYaw#(Body_Mesh),EntityRoll#(Body_Mesh)
	TurnEntity FR_Wheel,0,Turn#,0 
	PositionEntity FL_Wheel,TOKRB_GetX#(FL_Spr_RB),TOKRB_GetY#(FL_Spr_RB),TOKRB_GetZ#(FL_Spr_RB)
	RotateEntity FL_Wheel,EntityPitch#(Body_Mesh),EntityYaw#(Body_Mesh),EntityRoll#(Body_Mesh)
	TurnEntity FL_Wheel,0,Turn#,0 
	PositionEntity RR_Wheel,TOKRB_GetX#(RR_Spr_RB),TOKRB_GetY#(RR_Spr_RB),TOKRB_GetZ#(RR_Spr_RB)
	RotateEntity RR_Wheel,EntityPitch#(Body_Mesh),EntityYaw#(Body_Mesh),EntityRoll#(Body_Mesh)
	PositionEntity RL_Wheel,TOKRB_GetX#(RL_Spr_RB),TOKRB_GetY#(RL_Spr_RB),TOKRB_GetZ#(RL_Spr_RB)
	RotateEntity RL_Wheel,EntityPitch#(Body_Mesh),EntityYaw#(Body_Mesh),EntityRoll#(Body_Mesh)

 	PointEntity camera,Body_Mesh

	UpdateSpring 1.2,-0.5,-1.5,RR_Spr_RB,50,6.0,1.1
	UpdateSpring -1.2,-0.5,-1.5,RL_Spr_RB,50,6.0,1.1
	UpdateSpring 1.2,-0.5,1.65,FR_Spr_RB,50,6.0,1.1
	UpdateSpring -1.2,-0.5,1.65,FL_Spr_RB,50,6.0,1.1

	RRColl=False
	RLColl=False
	FRColl=False
	FLColl=False
	;Check Colliders
	If TOKSIM_GetCollisionCount()>0 Then
		 For c=0 To TOKSIM_GetCollisionCount()-1
			If PeekInt(ColBank,0+(c*104))=RR_Spr_RB Then RRColl=True
			If PeekInt(ColBank,0+(c*104))=RL_Spr_RB Then RLColl=True
			If PeekInt(ColBank,0+(c*104))=FR_Spr_RB Then FRColl=True
			If PeekInt(ColBank,0+(c*104))=FL_Spr_RB Then FLColl=True
	     Next
	EndIf

	;Driving-force

 If KeyDown(200) Then
  Acc#=Acc#+1.0
  If Acc#>11 Then Acc#=11
 ElseIf KeyDown(208) Then
  Acc#=Acc#-1.0
  If Acc#<6.0 Then Acc#=-6.0
 Else
  Acc#=Acc#*0.95
  If Acc#>-0.01 And Acc#<0.01 Then Acc#=0.0
 EndIf
	
	TFormVector 0,0,1,Body_Mesh,0
	vx#=TFormedX#()
	vy#=TFormedY#()
	vz#=TFormedZ#()
	
	 If RRColl=True Then
	  TOKRB_ApplyImpulse RR_Spr_RB,vx#*acc#*timestep#,vy#*acc#*timestep#,vz#*acc#*timestep#
     EndIf
	 If RLColl=True Then
	  TOKRB_ApplyImpulse RL_Spr_RB,vx#*acc#*timestep#,vy#*acc#*timestep#,vz#*acc#*timestep#
	 EndIf

	CarVelx#=TOKRB_GetVelocityX#(Body_RB)
	CarVely#=TOKRB_GetVelocityY#(Body_RB)
	CarVelz#=TOKRB_GetVelocityZ#(Body_RB)
	TFormNormal 0,0,1,Body_Mesh,0
	CarVel#=Abs(DotProduct#(TFormedX#(),TFormedY#(),TFormedZ#(),CarVelx#,CarVely#,CarVelz#))
	TurnFactor#=1.0-((1.0/35.0)*CarVel#)

MaxTurn#=27.0
CurrTurn#=MaxTurn#*TurnFactor#
If KeyDown(205) Then
 Turn#=Turn#-0.7
 If Turn#<-MaxTurn#*TurnFactor# Then Turn#=-MaxTurn#*TurnFactor#
ElseIf KeyDown(203) Then
 Turn#=Turn#+0.7
 If Turn#>MaxTurn#*TurnFactor# Then Turn#=MaxTurn#*TurnFactor#
Else
 Turn=Turn*0.95
 If Turn#>-0.1 And Turn#<0.1 Then Turn#=0.0
EndIf

	AngVelx#=TOKRB_GetAngularVelocityX#(Body_RB)
	AngVely#=TOKRB_GetAngularVelocityY#(Body_RB)
	AngVelz#=TOKRB_GetAngularVelocityZ#(Body_RB)
	TFormNormal 0,1,0,Body_Mesh,0
	AngVel#=Abs(DotProduct#(TFormedX#(),TFormedY#(),TFormedZ#(),AngVelx#,AngVely#,AngVelz#))

If KeyHit(57) Or (AngVel#>1.0 And CarVel#>12.0) Then
 Slip=True
EndIf

	If Slip=True Then 
	 GripFactor#=0.99
	EndIf	
	If AngVel#<0.7 And Slip=True Then 
	 GripFactor#=0.98
	 ;Slip=False
	EndIf	
	If AngVel#<0.5 And Slip=True Then 
	 GripFactor#=0.97
	 ;Slip=False
	EndIf	
	If AngVel#<0.3 And Slip=True Then 
	 GripFactor#=0.9
	 Slip=False
	EndIf	


If KeyHit(16) Then
 Slip=True
 TOKRB_ApplyTwist Body_RB,0,50,0
EndIf
	
	;Friction

	;Find sideslip-speed for RightRearWheel
    Vx#=TOKRB_GetVelocityX#(RR_Spr_RB)
    Vy#=TOKRB_GetVelocityY#(RR_Spr_RB)
    Vz#=TOKRB_GetVelocityZ#(RR_Spr_RB)
	TFormVector Vx#,Vy#,Vz#,0,Body_Mesh
	TFormVector TFormedX#()*GripFactor#,TFormedY#(),TFormedZ#(),Body_Mesh,0
	If RRColl=True Then
	 TOKRB_SetVelocity RR_Spr_RB,TFormedX#(),TFormedY#(),TFormedZ#()
 	EndIf

	;Find sideslip-speed for LeftRearWheel
    Vx#=TOKRB_GetVelocityX#(RL_Spr_RB)
    Vy#=TOKRB_GetVelocityY#(RL_Spr_RB)
    Vz#=TOKRB_GetVelocityZ#(RL_Spr_RB)
	TFormVector Vx#,Vy#,Vz#,0,Body_Mesh
	TFormVector TFormedX#()*GripFactor#,TFormedY#(),TFormedZ#(),Body_Mesh,0
	If RLColl=True Then
	 TOKRB_SetVelocity RL_Spr_RB,TFormedX#(),TFormedY#(),TFormedZ#()
	EndIf
	
	;Find sideslip-speed for RightFrontWheel
    Vx#=TOKRB_GetVelocityX#(FR_Spr_RB)
    Vy#=TOKRB_GetVelocityY#(FR_Spr_RB)
    Vz#=TOKRB_GetVelocityZ#(FR_Spr_RB)
	TFormVector Vx#,Vy#,Vz#,0,FR_Wheel
	TFormVector TFormedX#()*GripFactor#,TFormedY#(),TFormedZ#(),FR_Wheel,0
	If FRColl=True Then
	 TOKRB_SetVelocity FR_Spr_RB,TFormedX#(),TFormedY#(),TFormedZ#()
	EndIf
	
	;Find sideslip-speed for LeftFrontWheel
    Vx#=TOKRB_GetVelocityX#(FL_Spr_RB)
    Vy#=TOKRB_GetVelocityY#(FL_Spr_RB)
    Vz#=TOKRB_GetVelocityZ#(FL_Spr_RB)
	TFormVector Vx#,Vy#,Vz#,0,FL_Wheel
	TFormVector TFormedX#()*GripFactor#,TFormedY#(),TFormedZ#(),FL_Wheel,0
	If FLColl=True Then
	 TOKRB_SetVelocity FL_Spr_RB,TFormedX#(),TFormedY#(),TFormedZ#()
	EndIf


	;Drag
	TFormNormal 0,0,-1,Body_Mesh,0
	dragConstant# = 1.1
 	velX#=TOKRB_GetVelocityX#(Body_RB)
 	velY#=TOKRB_GetVelocityY#(Body_RB)
 	velZ#=TOKRB_GetVelocityZ#(Body_RB)

 	dot#=DotProduct#(TFormedX#(),TFormedY#(),TFormedZ#(),velX#,velY#,velZ#)
 	dragX#=dot#*TFormedX#()*-dragConstant#
 	dragY#=dot#*TFormedY#()*-dragConstant#
 	dragZ#=dot#*TFormedZ#()*-dragConstant#
	TOKRB_ApplyImpulse Body_RB,dragX#*timestep#,dragY#*timestep#,dragZ#*timestep#


	;Camera
	PositionEntity camtargetpivot,EntityX#(Body_Mesh),EntityY#(Body_Mesh),EntityZ#(Body_Mesh)
	RotateEntity camtargetpivot,EntityPitch#(Body_Mesh),EntityYaw#(Body_Mesh),EntityRoll#(Body_Mesh)
	MoveEntity camtargetpivot,0,3,-7
	UpdateCamera Camera,camtargetpivot,0.02


Next



	RenderWorld tween

	Flip False

Wend

TOKSIM_DestroySimulator()

End


Function UpdateSpring(px#,py#,pz#,Wheel_RB,Stiffness#,Damping#,SpringLength#)

;Add spring force
TFormPoint px#,py#,pz#,Body_Mesh,0
wpx#=TFormedX#()
wpy#=TFormedY#()
wpz#=TFormedZ#()

diffX#=wpx# - TOKRB_GetX#(Wheel_RB)
diffY#=wpy# - TOKRB_GetY#(Wheel_RB)
diffZ#=wpz# - TOKRB_GetZ#(Wheel_RB)
diffLen#=Sqr(diffX#*diffX#+diffY#*diffY#+diffZ#*diffZ#)
Displacement#=diffLen#-SpringLength#
nx#=diffx#/diffLen#
ny#=diffy#/diffLen#
nz#=diffz#/diffLen#
fx#=nx#*(Displacement#*Stiffness#)
fy#=ny#*(Displacement#*Stiffness#)
fz#=nz#*(Displacement#*Stiffness#)

;Add damping force
GetPointVel Body_RB,wpx#,wpy#,wpz#
Vx#=CProd\x#-TOKRB_GetVelocityX#(Wheel_RB)
Vy#=CProd\y#-TOKRB_GetVelocityY#(Wheel_RB)
Vz#=CProd\z#-TOKRB_GetVelocityZ#(Wheel_RB)

speed#=DotProduct#(nx#,ny#,nz#,Vx#,Vy#,Vz#)
dampX#=nx#*speed#*Damping#
dampY#=ny#*speed#*Damping#
dampZ#=nz#*speed#*Damping#

fx#=fx#+dampX#
fy#=fy#+dampY#
fz#=fz#+dampZ#

TOKRB_ApplyImpulse2 Body_RB,-fx#*timestep#,-fy#*timestep#,-fz#*timestep#,wpx#,wpy#,wpz#
TOKRB_ApplyImpulse Wheel_RB,fx#*timestep#,fy#*timestep#,fz#*timestep#

End Function

Function PlaceMesh(Mesh,RB)
   PositionEntity Mesh,TOKRB_GetX#(RB),TOKRB_GetY#(RB),TOKRB_GetZ#(RB) 
   RotateEntity Mesh,TOKRB_GetPitch#(RB),TOKRB_GetYaw#(RB),TOKRB_GetRoll#(RB),False
End Function


Function DotProduct#(x1#,y1#,z1#,x2#,y2#,z2#)
	DProd#=((x1#*x2#)+(y1#*y2#)+(z1#*z2#))
	Return DProd#
End Function
Function CrossProduct(x1#,y1#,z1#,x2#,y2#,z2#)
	CProd\x#=(y1#*z2#)-(z1#*y2#)
	CProd\y#=(z1#*x2#)-(x1#*z2#)
	CProd\z#=(x1#*y2#)-(y1#*x2#)
End Function

Function GetPointVel(RB,px#,py#,pz#)
 vx#=TOKRB_GetVelocityX#(RB)
 vy#=TOKRB_GetVelocityY#(RB)
 vz#=TOKRB_GetVelocityZ#(RB)
 avx#=TOKRB_GetAngularVelocityX#(RB)
 avy#=TOKRB_GetAngularVelocityY#(RB)
 avz#=TOKRB_GetAngularVelocityZ#(RB)
 CrossProduct avx#,avy#,avz#,px#-TOKRB_GetX#(RB),py#-TOKRB_GetY#(RB),pz#-TOKRB_GetZ#(RB)
 CProd\x#=CProd\x#+vx#
 CProd\y#=CProd\y#+vy#
 CProd\z#=CProd\z#+vz#
End Function

Function MakeTokCollider(mesh)
 scount=CountSurfaces(mesh)
 For ind=1 To scount
  surface=GetSurface(mesh,ind)
  ttltris=ttltris+CountTriangles(surface)
  ttlvert=ttlvert+CountVertices(surface)
 Next
 vertices=CreateBank(16*ttlvert)
 triangles=CreateBank(24*ttltris)
 offsetv=0
 offsett=0
 For ind=1 To scount
  surface = GetSurface(mesh,ind)
  ctr=CountTriangles(surface)
  tric=tric+cvt
  cvt=CountVertices(surface)
  ;fill bank with vertices
  For v=0 To cvt-1
   PokeFloat vertices,offsetv,VertexX#(surface,v)
   PokeFloat vertices,offsetv+4,VertexY#(surface,v)
   PokeFloat vertices,offsetv+8,VertexZ#(surface,v)
   PokeFloat vertices,offsetv+12,0.0
   offsetv=offsetv+16
  Next
  ;fill bank with triangles
  For v=0 To ctr-1
   PokeInt triangles,offsett,tric+TriangleVertex(surface,v,0)
   PokeInt triangles,offsett+4,tric+TriangleVertex(surface,v,1)
   PokeInt triangles,offsett+8,tric+TriangleVertex(surface,v,2)
   PokeInt triangles,offsett+12,2	; Material ID
   PokeInt triangles,offsett+16,0
   PokeInt triangles,offsett+20,0
   offsett=offsett+24
  Next
 Next

 ;Hand over the terrain data to Tokamak
 TOKSIM_SetStaticMesh vertices,ttlvert,triangles,ttltris
 ; Now we can free the banks as Tokamak has copied all data
 FreeBank vertices
 FreeBank triangles
End Function

Function RemoveComponent(x1#,y1#,z1#,x2#,y2#,z2#)
 tmpdot# = DotProduct#(x1#,y1#,z1#,x2#,y2#,z2#)
 CProd\x#=x1#-x2#*tmpdot#
 CProd\y#=y1#-y2#*tmpdot#
 CProd\z#=z1#-z2#*tmpdot#
End Function

Function GripFactor#(Vel#)
	If Vel#>=0.0 And Vel<3.0 Then
	 GripFactor#=0.50
	EndIf
	If Vel#>=3.0 And Vel<6.0 Then
	 GripFactor#=0.95
	EndIf
	If Vel#>=6.0 And Vel<10.0 Then
	 GripFactor#=0.97
	EndIf
	If Vel#>=10.0 And Vel<15.0 Then
	 GripFactor#=0.98
	EndIf
	If Vel#>=15.0 Then
	 GripFactor#=0.99
	EndIf
	Return 0.999
	Return GripFactor#
End Function


Function UpdateCamera(Camera,Target,Rate#)

CamX#=EntityX#(Camera)
CamY#=EntityY#(Camera)
CamZ#=EntityZ#(Camera)
DiffX#=EntityX#(Target)-CamX#
DiffY#=EntityY#(Target)-CamY#
DiffZ#=EntityZ#(Target)-CamZ#
TranslateEntity Camera,DiffX#*Rate#,DiffY#*Rate#,DiffZ#*Rate#

End Function