tokamak physics thread 3:

Blitz3D Forums/Blitz3D Programming/tokamak physics thread 3:

skidracer(Posted 2004) [#1]
Sorry, last thread was getting a bit long

download link: http://www.freewebs.com/sweenie

tokamak physics thread 1: http://www.blitzbasic.co.nz/Community/posts.php?topic=29381

tokamak physics thread 2: http://www.blitzbasic.com/Community/posts.php?topic=29680


Tom(Posted 2004) [#2]
Crap!

I didn't notice it was locked, and lost a whole bunch of text :) oops!

Anyways, in brief, Sweenie I think you may be right about gimble lock. If you check the rotating boxes example again, on the second loop the Blitz box shows -180 for yaw, yet it was 180 on the first loop. At some pitch angles -180 must give the same result as 180?

Rotation commands do seem to work ok! I sorted out my problem too, now to tackle cylinders with balls (O_o) :P

Sweenie, do you know if the inertia tensor for cylinders is also rotated if you rotate the geometry?

Tom


Beaker(Posted 2004) [#3]
Skid forgot to mention the Blitz_Tokamak forum here:
http://playerfactory.proboards25.com/index.cgi?board=tokamak


Shambler(Posted 2004) [#4]
Hope this works, I just did it in notepad =/


TESTDLL_API void __stdcall TOKRB_SetRotation(neRigidBody *RigidBody,float Pitch,float Yaw,float Roll)
{
	neQ BodyRot;
	float cr;
	float cp;
	float cy;
	float sr;
	float sp;
	float sy;
	float cpcy;
	float spsy;
	
	if (RigidBody)
	{
		cr = cos(NE_DEG_TO_RAD(Roll/2.0f));
		cp = cos(NE_DEG_TO_RAD(Pitch/2.0f));
		cy = cos(NE_DEG_TO_RAD(Yaw/2.0f));
		sr = sin(NE_DEG_TO_RAD(Roll/2.0f));
		sp = sin(NE_DEG_TO_RAD(Pitch/2.0f));
		sy = sin(NE_DEG_TO_RAD(Yaw/2.0f));
		
		cpcy = cp*cy;
		spsy = sp*sy;
		
		BodyRot.W = (cr*cpcy)+(sr*spsy);
		BodyRot.X = (sr*cpcy)-(cr*spsy);
		BodyRot.Y = (cy*sp*cr)+(sy*cp*sr);
		BodyRot.Z = (sy*cp*cr)-(cy*sp*sr);
		RigidBody->SetRotation(BodyRot);
	}
}




Tom(Posted 2004) [#5]
Everything seems to be working ok now, no rotation problems, no cylinder problems, limits all working as expected.

The -180 / 180 values must be an epsilon thing, because it does happen BB too. After ironing out more bugs in my code I'm finding that native BB rotations are matching up as expected in Tokamak.

Sweenie, maybe as you suggested, an additional method of setting rotation using matrices would be good, there's mroe than one way to skin a cat :P

I'll post any future tokamak specific stuff on the player factory BBS as these threads get a bit big.

Cheers!
Tom


bradford6(Posted 2004) [#6]
weird...
;# TOKAMAK DEMO v0.0017 (bradford6)
; Credits:
; SWEENIE for creating the TOKAMAK WRAPPER
; www.tokamakphysics.com to get SDK
; note:
; you must put TOKAMAK.DLL (from SDK) in system32
; must put sweenies tokamak files in blitz3d/userlibs directory
; this is rev -1 so it is very early and probably buggy, 

; constants
Const ENTS=100	; TOTAL NUMBER OF TOKAMAKPHYSICS ENTITIES
Const FPS=50
Const w=17, s=31, a=30, d=32, space=57

; globals
Global midw, midh ,world, campiv , camera , light, pickmarker
Global pictentity,pnx#,pny#,pnz#,pcx#,pcy#,pcz#
Global latspeed#,speed#,MX#,MY#
Global cubetex ,spheretex ,cyltex ,worldtex ,animtex
Global TOKS , period, time, imptime
Global bigfont , smallfont

Dim obj(ENTS)
Dim rb(ENTS)
Dim joint(ENTS)
SeedRnd MilliSecs()

Type tokrb
	Field tokid,entity,texture,pickmode
	Field name$
	Field posx#,posy#,posz#,scx#,scy#,scz#,pitch#,yaw#,roll#
	Field tokx#,toky#,tokz#,tokwidth#,tokheight#,tokdepth#,tokmass#
	Field lindamp#,angdamp#
	Field inert_width#,inert_depth#,inert_height#,inert_mass#
	

End Type

TOKSIM_CreateSimulator(ENTS,1,0,-10,0)
period=500/FPS
time=MilliSecs()-period
imptime=MilliSecs()


create3d_scene(800,600,16,2)

; animated bodies
    anWidth# = 10  anHeight#=4 anDepth#=10
	anx#=0  anyY#=20  anzZ#=0
	angdamp# = 0.002
	lindamp# = 0.001
	mass# = 2.0 
	inertia_tensor_mass# = 4.0  
	inertia_tensor_diam# = .1
	
	AnimBody = TOKAB_Create()
	animbodymesh = CreateCube() : ScaleEntity animbodymesh,anwidth#/2,anheight#/2,andepth#/2
	EntityTexture animbodymesh,animtex : EntityPickMode animbodymesh,2
	PositionEntity animbodymesh,anx#,anyY#,anzZ#

	TOKAB_AddBox(AnimBody,anWidth#,anHeight#,anDepth#)
	
	
	TOKAB_SetPosition(AnimBody,anx#,anyY#,anzZ#)
	
	;create_TOK_BALL(12,4,anx#-(anwidth#/2),any#+6,anz#-(andepth#/2),angdamp#,lindamp#,mass#,inertia_tensor_mass#,inertia_tensor_diam#,cubetex,"ball")

	
	
	;create_TOK_BALL(12,4,anx#-(anwidth#/2),any#+6,anz#-(andepth#/2),angdamp#,lindamp#,mass#,inertia_tensor_mass#,inertia_tensor_diam#,cubetex,"ball")

	For j = 1 To 20
		create_TOK_BOX(j/2,j/2,j/2,j*2.5,10,0,0.001,0.02,2,2,2,2,2,cubetex,"anim")
		TOKRB_CollideConnected(rb(toks),True)
		If j > 1 
			joint(j) = TOKJOINT_Create(3,rb(toks),rb(toks-1))
			TOKJOINT_SetType(joint(j),3)
			TOKJOINT_SetPositionAndRotationWorld(joint(j),j*2.5,10,0,0,0,0)
			TOKJOINT_Enable(joint(j),True)
			;TOKJOINT_SetJointLength(joint(j),3)
			;TOKJOINT_SetLowerLimit2 joint(j),-3.14*0.1 ; (-45 degrees)
			;TOKJOINT_SetUpperLimit2 joint(j),3.14*0.1  ; (+45 degrees)
			;TOKJOINT_EnableLimit2 joint(j),True 
		EndIf 
	Next
	
	;TOKAB_SetRotation(AnimBody,anPitch#,anYaw#,anRoll#)

; +++ MAIN LOOP START ++++++ MAIN LOOP START ++++++ MAIN LOOP START ++++++ MAIN LOOP START +++
.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.75/FPS,1)
	
			move_camera()
	
			UpdateWorld
			For i=1 To TOKS
					 If TOKRB_IsIdle(rb(i)) Then
					  	EntityAlpha obj(i),0.5
					 Else
						  EntityAlpha obj(i),1.0
						  TOKRB_Active(rb(i),True)
					
					 EndIf
			 
					 If EntityName(obj(i)) = "ball"
							; do stuff
					 EndIf
				
					 If EntityName(obj(i)) = "box"
							;If MouseDown(2) = 1 Then TOKRB_ApplyTwist(rb(i),0,150,0)
					 EndIf
				
				 PositionEntity obj(i),TOKRB_GetX#(rb(i)),TOKRB_GetY#(rb(i)),TOKRB_GetZ#(rb(i)) 
				 RotateEntity obj(i),TOKRB_GetPitch#(rb(i)),TOKRB_GetYaw#(rb(i)),TOKRB_GetRoll#(rb(i)),False
			Next

	Next

; Not sure wether to put this here or inside the for/next above...



.carmovement

animyaw# = animyaw# + 1
If animyaw# = 360 Then animyaw# = 1
TOKAB_SetRotation(Animbody,0,animYaw#,0) : RotateEntity animbodymesh,0,animyaw#,0

;accel# = 0.01
;force# = force# * .99

;TOKRB_ApplyImpulse rb(1),-(Sin(EntityYaw(obj(1)))*force#),-(Sin(EntityPitch(obj(1)))*force#),Cos(EntityYaw(obj(1)))*force#
;ok
;TOKRB_ApplyImpulse rb(2),-(Sin(EntityYaw(obj(1)))*force#),-(Sin(EntityPitch(obj(1)))*force#),Cos(EntityYaw(obj(1)))*force#
;TOKRB_ApplyImpulse rb(4),-(Sin(EntityYaw(obj(1)))*force#),-(Sin(EntityPitch(obj(1)))*force#),Cos(EntityYaw(obj(1)))*force#
;TOKRB_SetTorque rb(2),-(Cos(EntityYaw(obj(1)))*force#)/2,0,-(Sin(EntityYaw(obj(1)))*force#)/2
;TOKRB_ApplyTwist rb(3),-(Cos(EntityYaw(obj(1)))*force#)/2,0,-(Sin(EntityYaw(obj(1)))*force#)/2
;TOKRB_ApplyTwist rb(2),0,-(Sin(EntityYaw(obj(1)))*force#),0
carpitch# = EntityPitch(obj(1))
caryaw# = EntityYaw(obj(1))
carroll# = EntityRoll(obj(1))
caryaw_cos# = Cos(caryaw#)
caryaw_sin# = Sin(caryaw#)

	If KeyDown(200) = 1
				If force# < 0 Then force#=2

				force# = force# + .001
				If force# > 80 Then force = 80
				;TOKRB_ApplyImpulse rb(1),-(Sin(EntityYaw(obj(1)))*force#),-(Sin(EntityPitch(obj(1)))*force#),Cos(EntityYaw(obj(1)))*force#
	EndIf

	If KeyDown(208) = 1
				If force# > 0 Then force#=-2
			
				force# = force# - 0.001
				If force# < -25 Then force = -25
	EndIf
	
	
	;TOKRB_SetAngularMomentum(rb(6),caryaw_cos#*force#,0,caryaw_sin#*force#)
	;TOKRB_SetAngularMomentum(rb(7),caryaw_cos#*force#,0,caryaw_sin#*force#)

	
		
	ncaryaw# = caryaw# + turn#
	
	If KeyDown(203) = 1
		turn# = turn# + 0.05
		If turn#>40 Then turn# = 40
		
	EndIf
	If KeyDown(205) = 1
		turn# = turn# - 0.05
		If turn#<-40 Then turn# = -40
	EndIf

	;TOKRB_SetRotation(rb(2),carpitch#,ncaryaw#,carroll#)
	;TOKRB_SetRotation(rb(4),carpitch#,ncaryaw#,carroll#)




If MouseDown(2) = 1 Then place_rb(cubetex)
If MouseDown(1)=1 Then push_rigid_body()


RenderWorld tween
Color 255,255,255
Text 0,0,"Physics Time:"+TOKSIM_GetPhysicsTime()*1000.0+ " milliseconds"
Text 0,10,"Render Time:"+Str(elapsed)+ " milliseconds"
Text 0,20,"pnx"+pnx#+"  pny "+pny#+"  pnz  "+pnz# 
;Text 0,30,"Render Time:"+Str(elapsed)+ " milliseconds"
Text 0,40,"force: "+force#
;Text 0,50,"Render Time:"+Str(elapsed)+ " milliseconds"
Text 0,50,"camera X : "+EntityX(campiv)+"   Y : "+EntityY(campiv)+"  Z : "+EntityZ(campiv)

Color 255,0,0
Rect midw-4,midh-4,8,8,0
	Flip False

Wend

; == MAIN LOOP END ==== MAIN LOOP End ==== MAIN LOOP End ==== MAIN LOOP End ==== MAIN LOOP End ==


TOKSIM_DestroySimulator()

End

;==================================================================================
Function curvevalue#(newvalue#,oldvalue#,increments# )
	If increments>1 Then oldvalue#=oldvalue#-(oldvalue#-newvalue#)/increments
	If increments<=1 Then oldvalue=newvalue
	Return oldvalue#
End Function
;==================================================================================
Function move_camera()
	; Movement controls
	If KeyDown(w)=1 Then speed# = speed#+.03
	If KeyDown(a)=1 Then latspeed# = latspeed# - .02
	If KeyDown(s)=1 Then speed# = speed# -.03
	If KeyDown(d)=1 Then latspeed# = latspeed# + .02

latspeed#=latspeed#*.98
speed#=speed#*.98

MY#=curvevalue#(MouseYSpeed(),MY#,3 )
MX#=curvevalue#(MouseXSpeed(),MX#,3 )
TurnEntity campiv,MY#,-MX#,0 ; turn camera up and down
;TurnEntity campiv,0,-MX#,0 ;  turn nnn left --right
RotateEntity campiv,EntityPitch(campiv),EntityYaw(campiv),0
If EntityPitch(campiv)>88 Then RotateEntity campiv,88,EntityYaw(campiv),EntityRoll(campiv)
If EntityPitch(campiv)<-88 Then RotateEntity campiv,-88,EntityYaw(campiv),EntityRoll(campiv)

MoveMouse 100,100

MoveEntity campiv,latspeed#,0,speed#
	


End Function
;==================================================================================
Function create_cube_texture()
	tex = CreateTexture(64,64)
	ScaleTexture tex,.5,.5
	SetBuffer TextureBuffer(tex)
		Color 20,20,200
		Rect 0,0,64,64
		Color 255,255,255
		Rect 0,0,32,32
		Rect 32,32,64,64
		Color 0,0,0
		Rect 0,0,64,64,0
	SetBuffer BackBuffer()
	Return tex
	
End Function

Function create_anim_texture()
	tex = CreateTexture(256,256)
	;ScaleTexture tex,.5,.5
	SetBuffer TextureBuffer(tex)
		Color 240,240,241 : Rect 5,5,250,250
		
		Color 150,150,50
		Rect 5,5,128,128
		Color 200,200,100
		Rect 5,5,128,128
		Rect 128,128,250,250
		;Color 200,200,0
		;Rect 5,5,128,128,0

		Color 5,5,5
		SetFont bigfont
		Text 128+3,90+3,"TOKAMAK",1,1
		
		Text 128+3,128+3,"Animated Body",1,1
		
		Color 255,0,0
		SetFont bigfont
		Text 128,90,"TOKAMAK",1,1
		Color 0,0,255
		Text 128,128,"Animated Body",1,1
		SetFont smallfont
		
	SetBuffer BackBuffer()
	Return tex
	
End Function


Function create_world_texture()
	tex = CreateTexture(128,128)
	ScaleTexture tex,.25,.25
	SetBuffer TextureBuffer(tex)
		Color 100,100,100
		Rect 0,0,128,128
		Color 50,50,50
		Rect 0,0,64,64
		Rect 64,64,128,128
		Color 200,200,0
		Rect 0,0,128,128,0
		

	SetBuffer BackBuffer()
	Return tex
	
End Function

;==================================================================================
Function create_sphere_texture()
	tex = CreateTexture(128,128)
	SetBuffer TextureBuffer(tex)
		Color 0,200,0
		Rect 0,0,128,128
		Color 255,255,0
		Rect 0,0,64,64
		Rect 64,64,128,128
		Color 0,0,0
		Rect 0,0,64,64,0
		Color 0,0,0
		Rect 64,64,128,128,0
		Color 0,0,0
		Rect 0,0,128,128,0
	ScaleTexture tex,.5,.5


	SetBuffer BackBuffer()
	Return tex

	
End Function

;==================================================================================
Function create_cyl_texture()
	tex = CreateTexture(128,128)
	SetBuffer TextureBuffer(tex)
		Color 0,0,0
		Rect 0,0,128,128
		Color 255,0,0
		Rect 0,0,64,64
		Rect 64,64,128,128
	SetBuffer BackBuffer()
	Color 255,255,0 ; YELLOW
	Return tex

	
End Function

;==================================================================================
Function campick()
	pictentity = 0
	CameraPick(camera,midw,midh)
	pictentity = PickedEntity() 
	If Pictentity<>0
		
		;EntityAlpha pictentity,.7	
		pnx# = PickedNX#()
		pny# = PickedNY#()
		pnz# = PickedNZ#()	
		pcx# = PickedX#()
		pcy# = PickedY#()
		pcz# = PickedZ#()

	
	EndIf
	

End Function

Function create_TOK_BOX(xs#,ys#,zs#,xp#,yp#,zp#,damp#,angdamp#,mass#,iw#,ih#,id#,imass#,texture,name$)

			TOKS = TOKS+1
			If TOKS>ENTS 
				TOKS = ENTS
				Return
			EndIf
			obj(TOKS) = CreateCube()
			NameEntity obj(toks),name$
			ScaleEntity obj(TOKS),xs#/2,ys#/2,zs#/2
			EntityPickMode obj(TOKS),2
			EntityTexture obj(TOKS),texture
			rb(TOKS) = TOKRB_Create()
			TOKRB_SetSleepingParameter(rb(TOKS),-100)
			TOKRB_AddBox rb(TOKS),xs#,ys#,zs#
			TOKRB_SetPosition(rb(TOKS),xp#,yp#,zp#)
			TOKRB_SetLinearDamping rb(TOKS),damp#
			TOKRB_SetAngularDamping rb(TOKS),angdamp# 

			TOKRB_SetMass rb(TOKS),mass#
			TOKRB_SetBoxInertiaTensor rb(TOKS),iw#,ih#,id#,imass# 
			
			

End Function

Function create_TOK_BALL(segs,sc#,xp#,yp#,zp#,angdamp#,lindamp#,mass#,IT1#,IT2#,texture,name$)
			  TOKS = TOKS+1
			  
				If TOKS>ENTS 
					TOKS = ENTS
					Return
				EndIf
	
			
				obj(TOKS) = CreateSphere(segs)
				NameEntity obj(toks),name$

			  ScaleEntity obj(TOKS),sc#/2,sc#/2,sc#/2
			  EntityPickMode obj(TOKS),2

			  EntityTexture obj(TOKS),texture
			  rb(TOKS) = TOKRB_Create()
			  TOKRB_AddSphere rb(TOKS),sc#
			  TOKRB_SetPosition(rb(TOKS),xp#,yp#,zp#)
			  TOKRB_SetAngularDamping rb(TOKS),angdamp# 
			  TOKRB_SetLinearDamping rb(TOKS),lindamp#
			  TOKRB_SetMass rb(TOKS),mass#
			  TOKRB_SetSphereInertiaTensor rb(TOKS),IT1#,IT2#  
End Function



Function create_TOK_CYL(segs,diameter#,height#,xp#,yp#,zp#,angdamp#,lindamp#,mass#,Id#,Ih#,Imass#,texture,name$)

			TOKS = TOKS+1
			  
				If TOKS>ENTS 
					TOKS = ENTS
					Return
				EndIf
			
			obj(TOKS) = CreateCylinder(segs)
 				EntityPickMode obj(TOKS),2
  			 EntityTexture obj(TOKS),texture
			  rb(TOKS) = TOKRB_Create()
			  TOKRB_AddCylinder rb(TOKS),diameter#,height#
			  ScaleEntity obj(TOKS),diameter#/1.95,height#,diameter#/1.95
			  TOKRB_SetPosition(rb(TOKS),xp#,yp#,zp#)
			  TOKRB_SetAngularDamping rb(TOKS),angdamp# 
			  TOKRB_SetLinearDamping rb(TOKS),lindamp#
			  TOKRB_SetMass rb(TOKS),mass#
			  TOKRB_SetCylinderInertiaTensor rb(TOKS),Id#,Ih#,Imass# 
			  TOKRB_Active(rb(toks),True)
			;TOKRB_CollideConnected(rb(toks),True)
End Function
;==================================================================================

Function place_rb(tex)
	
		campick()
		If pictentity>0
			PositionEntity pickmarker,pcx#,pcy#,pcz#
			;create_TOK_BOX(xs#,ys#,zs#,xp#,yp#,zp#,damp#,angdamp#,mass#,iw#,ih#,id#,imass#,texture,name$)
	
			create_TOK_BOX(4,4,4,pcx#,pcy#+2,pcz#,0.001,0.002,2,4,4,4,2,tex,"foo")
			Repeat : Until MouseDown(2) = 0
			
	 	EndIf
	FlushMouse()
End Function
		
;==================================================================================



;==================================================================================

Function push_rigid_body()
	
		campick()
	 	For n = 1 To TOKS
			If pictentity = obj(n)
				i = n
				
				If KeyDown(29) Or KeyDown(157)
				
					TOKRB_ApplyImpulse2 rb(i),-pnx#*15,-pny#*15,-pnz#*15,pcx#,pcy#,pcz# 
				Else
					TOKRB_ApplyImpulse2 rb(i),-pnx#,-pny#,-pnz#,pcx#,pcy#,pcz# 				;TOKRB_ApplyImpulse rb(i),-pnx#,pny#,-pnz#
				EndIf
			EndIf
		Next		
End Function
		
;==================================================================================
Function create3d_scene(gwidth,gheight,gdepth,gmode)
	Graphics3D gwidth,gheight,gdepth,gmode
	midw = GraphicsWidth()/2
	midh =GraphicsHeight()/2
	SetBuffer BackBuffer()
	HidePointer 
	WireFrame False
	
	bigfont=LoadFont("Arial",32,True) 
	smallfont=LoadFont("Arial",12,True) 
	; camera
	campiv = CreatePivot()
	camera = CreateCamera(campiv)
	CameraClsColor(camera,0,0,0)
	
	
	centerpivot = CreatePivot()
	PositionEntity centerpivot ,0,10,0

	PositionEntity campiv,0,30,-20
	PointEntity campiv,centerpivot  
	
	
	; light
	light=CreateLight()
	PositionEntity light,-20,10,-20
	FlushMouse() 

	; create some textures
	animtex = create_anim_texture()
	cubetex = create_cube_texture()
	spheretex = create_sphere_texture()
	cyltex = create_cyl_texture()
	worldtex = create_world_texture()
	pickmarker = CreateSphere(4) : EntityAlpha pickmarker,.75 : EntityTexture pickmarker,spheretex
	
	; create (or load) TOKAMAK STATIC MESH	
	world = CreateCube()
	;world = LoadMesh("roadmap2.3ds")
	EntityPickMode world,2
	sc# = 50
	ScaleMesh world,sc#,sc#,sc# : PositionMesh world,0,sc#,0 : FlipMesh world : EntityTexture world,worldtex
	obstacle = CreateCube() : EntityTexture obstacle,cyltex : ScaleMesh obstacle,5,10,10 : PositionMesh obstacle,-10,16,0
	RotateMesh obstacle ,0,0,65 : AddMesh obstacle,world

	obstacle2 = CreateSphere(6) : EntityTexture obstacle2,cubetex : ScaleMesh obstacle2,10,4,10 : PositionMesh obstacle2,32,-1,30
	RotateMesh obstacle2 ,0,0,0 : AddMesh obstacle2,world
	
	
	; send the woeld mesh to TOKAMAK
	maketokcollider(world)
	; CREATE some stacked TOKAMAK boxes
	For columns = 1 To 4
		For rows = 1 To 4
			bxs#= 4 bys#= 4 bzs#=4 
			bdamp# = 0.001 
			bangdamp# =0.0002 
			bmass# = 4
			biw# = 4 bih# = 4 bid# = 4 
			bimass# = 4
			
			create_TOK_BOX(bxs#,bys#,bzs#,(columns*4)+20,(rows*4)+1,16,bdamp#,bangdamp#,bmass#,biw#,bih#,bid#,bimass#,cubetex,"box")
			
			;create_TOK_BOX(4,4,4,pcx#,pcy#+2,pcz#,0.001,0.002,2,4,4,4,2,tex,"foo")

			
			;create_TOK_BOX(4,4,4,(columns*4)+20,rows*4,16,0.001,0.001,1.5,4,4,4,2,cubetex,"car")

			;create_TOK_BOX(4,4,4,(columns*4)+20,(rows*4)+1,16,0.02,0.001,4,4,4,4,2,cubetex,"car")
		Next
	Next


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,0
   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



dangerdave(Posted 2004) [#7]
That is weird.


bradford6(Posted 2004) [#8]
the 'snake' seems to move by itself, I am applying no force to it. I am asuming the weight of the RB's are propelling it forward?


AbbaRue(Posted 2004) [#9]
That's cool. If that worked in real life we would have a source of endless power.
It would be interesting to put a few of these into a larger world and see how they interact.
I noticed sometimes it acts like its having nervious brakedown or something. Interesting effects, almost like it has a mind of its own.


JoshK(Posted 2004) [#10]
That snake looks like the links are inside each other, so they keep colliding and causing those errors.


smilertoo(Posted 2004) [#11]
Its alive.....run.


Mustang(Posted 2004) [#12]
It's the basic "problem" of "exploding physics"... try for example Tom's Orc demo and walk first in the middle of the boxes - and then enable physics! :)


Shambler(Posted 2004) [#13]
How can you get objects to fall at a realistic rate without increasing gravity to -100?

Everyone seems to set it at -10, but it just doesn't look real at all.


Sweenie(Posted 2004) [#14]
Well, the scale of everything is an important thing.
If the gravity is -10 (it's close to earth gravity 9.8xx)
Then if you have a box that is 2x2x2 units that would mean that the box is 2x2x2 meters in size.
So if you create a big box in tokamak that is the above size and then create a small box that is 0.2x0.2x0.2 meters you will notice that the small box will appear to fall and flip over much faster then big box.

But some "tuning" might be needed sometimes.

What are the sizes of the objects you refer too?


Shambler(Posted 2004) [#15]
Thanks Sweenie that explains alot because it means some of my objects are around 100metres in size =)


bradford6(Posted 2004) [#16]
Sweenie,
Thank you for the hard work you have already put into this. I guess I am waiting for the next release (I don't want to spend too much time learning something that is going to change drastically)

What changes or updates do you have planned?


Sweenie(Posted 2004) [#17]
Well, why don't you take a look yourself. ;)
Check the wrappersite.

I have changed one VERY IMPORTANT thing.
It's the creation of the simulator.
Before v0.4 I only let the user set the maximum amount of rigid and animated bodies and let the geometry,joint and so on be at default which could lead to a crash if the user created more joints or geometries than the default value allows.
The default maximum amount of joints is for example 100 and if you would have created 101 joints you would get a crash.

Now you can specify all these maximum values before the simulator is created. If you don't set these values, default values will be used.(Check tokamak.decls for default values)


RepeatUntil(Posted 2004) [#18]
Thanks for this version 0.4, sweenie!!
I will spend my week-end testing the friction and restitution stuff!!


BlitzSupport(Posted 2004) [#19]
Literally just ran the demos here. The damping joint thing looks really slick, and as for the car demo -- absolutely brilliant (once you bump up the power!).

Thanks, Sweenie!


RayTracer(Posted 2004) [#20]
Great work sweenie!


bradford6(Posted 2004) [#21]
Awesome, Sweenie.

fantastic work on the Damping, The car demo looks like mine (except yours works :) )

Thanks alot for ruining my weekend, I was planning on watching movies and chilling out, Now I am forced (by the invisible hand of blitz) to make Tokamak demos!


IPete2(Posted 2004) [#22]
@Shambler:
Try altering the code as follows:

period=400/FPS

and additionally...

TOKSIM_Advance(2.5/FPS,1)

I find that these improve the realism of the movement somewhat, although I gues for different PCs this will have dfferent effects.


@Sweenie... Man this is so cool, a car demo with real physics and materials, you just keep widening the horizons of B3d with all this lovely stuff, Thank you so much!

IPete2.


Ricky Smith(Posted 2004) [#23]
This just keeps getting better ! Your work is very much appreciated (and the Tokamak people of course).
This is going to make such a difference to future Blitz games !


Pongo(Posted 2004) [#24]
I made a few very small changes to the car demo from the last wrapper version. (glad to see the meshes getting used) No code changes, just played around with parameters a bit to try to get a better feel. Wish I could increase friction more and stop some of the flipping over, but I think it's an improvement.

Also added in the infield mesh and track fence.
edit: you will need to get these meshes if you do not have them. Look for the thread "giving back to the community" in the blitz3d section

Pongo

; Thanks to Pongo for the Racetrack and Carmodel.

Const FPS=90

Graphics3D 1024,768
SetBuffer BackBuffer()

WireFrame False

camera = CreateCamera()
PositionEntity camera,70,20,0
CameraZoom camera,2

TOKSIM_CreateSimulator(0,-30,0)

TOKSIM_SetMaterial 1,30.0,12.0 
TOKSIM_SetMaterial 2,10.0,10.0  

fence=LoadMesh("track_fence.b3d")
ScaleMesh fence,0.25,0.25,0.25


infield=LoadMesh("mud_infield.b3d")
ScaleMesh infield,0.25,0.25,0.25


Terrain = LoadMesh("oval_racetrack.b3d")
ScaleMesh Terrain,0.25,0.25,0.25

AddMesh terrain,infield
FreeEntity terrain

MakeTokCollider(infield)


;MakeTokCollider(Terrain)

;Ground = CreateCube()
;ScaleMesh Ground,0.5,0.5,0.5
;ScaleEntity Ground,300,10,300 
;PositionEntity Ground,0,-5,0
;EntityColor Ground,10,10,100
 
;ABGround = TOKAB_Create()
;geom = TOKAB_AddBox(ABGround,300,10,300)
;TOKGEOM_SetMaterialIndex geom,2
;TOKAB_SetPosition ABGround,0,-5,0

Jump = CreateCube()
ScaleMesh Jump,0.5,0.5,0.5
ScaleEntity Jump,10,10,10 
PositionEntity Jump,0,-4.5,20
RotateEntity Jump,0,0,-25
EntityColor Jump,30,130,30
 
ABJump = TOKAB_Create()
geom = TOKAB_AddBox(ABJump,10,10,10)
TOKGEOM_SetMaterialIndex geom,2
TOKAB_SetPosition ABJump,0,-4.5,20
TOKAB_SetRotation ABJump,0,0,-25

YOffset#=2.0

;Build Chassi
Chassi_Mesh = LoadMesh("truck_body.b3d")
ScaleMesh Chassi_Mesh,0.3,0.3,0.3
RotateMesh Chassi_Mesh,0,180,0 
PositionMesh Chassi_Mesh,0,-1.5,0 

Chassi_RB = TOKRB_Create()
TOKRB_AddBox Chassi_RB,2.0,1.3,4.0
TOKRB_SetMass Chassi_RB,40.0
TOKRB_SetBoxInertiaTensor Chassi_RB,1.5,1.0,3.0,50.0 
TOKRB_SetLinearDamping Chassi_RB,0.003
TOKRB_SetAngularDamping Chassi_RB,0.005
TOKRB_SetPosition Chassi_RB,0,0.0+YOffset#,0

;Build RearLeft Wheel
RLWheel_Mesh = LoadMesh("truck_wheel.b3d")
ScaleMesh RLWheel_Mesh,0.32,0.32,0.32
RotateMesh RLWheel_Mesh,0,180,0 

RLWheel_RB = TOKRB_Create()
geom = TOKRB_AddSphere(RLWheel_RB,1.1)
TOKGEOM_SetMaterialIndex geom,1
TOKRB_SetMass RLWheel_RB,3.0
TOKRB_SetSphereInertiaTensor RLWheel_RB,1.2,1.5 
TOKRB_SetPosition RLWheel_RB,-1.2,-0.7+YOffset#,-1.5 
TOKRB_SetLinearDamping RLWheel_RB,0.001
TOKRB_SetAngularDamping RLWheel_RB,0.02

;Build RearRight Wheel
RRWheel_Mesh = LoadMesh("truck_wheel.b3d")
ScaleMesh RRWheel_Mesh,0.32,0.32,0.32
RotateMesh RRWheel_Mesh,0,180,0 

RRWheel_RB = TOKRB_Create()
geom=TOKRB_AddSphere(RRWheel_RB,1.1)
TOKGEOM_SetMaterialIndex geom,1
TOKRB_SetMass RRWheel_RB,3.0
TOKRB_SetSphereInertiaTensor RRWheel_RB,1.2,1.5 
TOKRB_SetPosition RRWheel_RB,1.2,-0.7+YOffset#,-1.5 
TOKRB_SetLinearDamping RRWheel_RB,0.001
TOKRB_SetAngularDamping RRWheel_RB,0.02

;Build FrontLeft Wheel
FLWheel_Mesh = LoadMesh("truck_wheel.b3d")
ScaleMesh FLWheel_Mesh,0.32,0.32,0.32
RotateMesh FLWheel_Mesh,0,180,0 

FLWheel_RB = TOKRB_Create()
geom=TOKRB_AddSphere(FLWheel_RB,1.1)
TOKGEOM_SetMaterialIndex geom,1
TOKRB_SetMass FLWheel_RB,3.0
TOKRB_SetSphereInertiaTensor FLWheel_RB,1.2,1.5 
TOKRB_SetPosition FLWheel_RB,-1.2,-0.7+YOffset#,1.7 
TOKRB_SetLinearDamping FLWheel_RB,0.001
TOKRB_SetAngularDamping FLWheel_RB,0.02
TOKRB_CollideConnected FLWheel_RB,False

;Build FrontRight Wheel
FRWheel_Mesh = LoadMesh("truck_wheel.b3d")
ScaleMesh FRWheel_Mesh,0.32,0.32,0.32
RotateMesh FRWheel_Mesh,0,180,0 

FRWheel_RB = TOKRB_Create()
geom=TOKRB_AddSphere(FRWheel_RB,1.1)
TOKGEOM_SetMaterialIndex geom,1
TOKRB_SetMass FRWheel_RB,3.0
TOKRB_SetSphereInertiaTensor FRWheel_RB,1.2,1.5 
TOKRB_SetPosition FRWheel_RB,1.2,-0.7+YOffset#,1.7 
TOKRB_SetLinearDamping FRWheel_RB,0.001
TOKRB_SetAngularDamping FRWheel_RB,0.02
TOKRB_CollideConnected FRWheel_RB,False

; Create Rear Axles
RLAxle = TOKJOINT_Create(2,RLWheel_RB,Chassi_RB)
TOKJOINT_SetType RLAxle,3 ; Hinge
TOKJOINT_SetPositionAndRotationWorld RLAxle,-1.2,-0.7+YOffset#,-1.5,0,0,90
TOKJOINT_Enable RLAxle,True 
TOKJOINT_SetDampingFactor RLAxle,0.5 
TOKJOINT_SetEpsilon RLAxle,0.0
TOKJOINT_SetIterations RLAxle,10  

RRAxle = TOKJOINT_Create(2,RRWheel_RB,Chassi_RB)
TOKJOINT_SetType RRAxle,3 ; Hinge
TOKJOINT_SetPositionAndRotationWorld RRAxle,1.2,-0.7+YOffset#,-1.5,0,0,90
TOKJOINT_Enable RRAxle,True 
TOKJOINT_SetDampingFactor RRAxle,0.5 
TOKJOINT_SetEpsilon RRAxle,0.0
TOKJOINT_SetIterations RRAxle,10  

; Create Steering Axles

FLJointConnector = TOKRB_Create()
TOKRB_SetPosition FLJointConnector,-1.2,-0.7+YOffset#,1.7
FLSteering = TOKJOINT_Create(2,FLJointConnector,Chassi_RB)
TOKJOINT_SetType FLSteering,3 ; Hinge
TOKJOINT_SetPositionAndRotationWorld FLSteering,-1.2,-0.7+YOffset#,1.7,0,0,0
TOKJOINT_Enable FLSteering,True 
TOKJOINT_SetLowerLimit FLSteering,-3.14*0.25 ; -45 Degrees
TOKJOINT_SetUpperLimit FLSteering,3.14*0.25 ; +45 Degrees
TOKJOINT_EnableLimit FLSteering,False 
;TOKJOINT_SetDampingFactor FLSteering,5.0
TOKJOINT_SetEpsilon FLSteering,0.0
TOKJOINT_SetIterations FLSteering,10  

FRJointConnector = TOKRB_Create()
TOKRB_SetPosition FRJointConnector,1.2,-0.7+YOffset#,1.7
FRSteering = TOKJOINT_Create(2,FRJointConnector,Chassi_RB)
TOKJOINT_SetType FRSteering,3 ; Hinge
TOKJOINT_SetPositionAndRotationWorld FRSteering,1.2,-0.7+YOffset#,1.7,0,0,0
TOKJOINT_Enable FRSteering,True 
TOKJOINT_SetLowerLimit FRSteering,-3.14*0.25 ; -45 Degrees
TOKJOINT_SetUpperLimit FRSteering,3.14*0.25 ; +45 Degrees
TOKJOINT_EnableLimit FRSteering,False
;TOKJOINT_SetDampingFactor FRSteering,5.0
TOKJOINT_SetEpsilon FRSteering,0.0
TOKJOINT_SetIterations FRSteering,10  

; Create Front Axles

FLAxle = TOKJOINT_Create(2,FLWheel_RB,FLJointConnector)
TOKJOINT_SetType FLAxle,3 ; Hinge
TOKJOINT_SetPositionAndRotationWorld FLAxle,-1.2,-0.7+YOffset#,1.7,0,0,90
TOKJOINT_Enable FLAxle,True 
TOKJOINT_SetDampingFactor FLAxle,0.5
TOKJOINT_SetEpsilon FLAxle,0.0
TOKJOINT_SetIterations FLAxle,10  

FRAxle = TOKJOINT_Create(2,FRWheel_RB,FRJointConnector)
TOKJOINT_SetType FRAxle,3 ; Hinge
TOKJOINT_SetPositionAndRotationWorld FRAxle,1.2,-0.7+YOffset#,1.7,0,0,90
TOKJOINT_Enable FRAxle,True 
TOKJOINT_SetDampingFactor FRAxle,0.5
TOKJOINT_SetEpsilon FRAxle,0.0
TOKJOINT_SetIterations FRAxle,10  

Centerpivot = CreatePivot()
light=CreateLight()
PositionEntity light,7,15,-5
PointEntity light,Centerpivot

period=1000/FPS
time=MilliSecs()-period

temppivot=CreatePivot()

; 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

; Steering

  If KeyDown(203) And SteeringAngle#<20 Then
   SteeringAngle#=SteeringAngle#+2
  ElseIf KeyDown(205) And SteeringAngle#>-20 Then
   SteeringAngle#=SteeringAngle#-2
  Else
   If SteeringAngle#>0 Then
     SteeringAngle#=SteeringAngle#-0.5
   ElseIf SteeringAngle#<0 Then
     SteeringAngle#=SteeringAngle#+0.5
   EndIf
  EndIf

  RotateEntity temppivot,TOKJOINT_GetFrameBPitch(FLSteering),TOKJOINT_GetFrameBYaw(FLSteering),TOKJOINT_GetFrameBRoll(FLSteering)
  TurnEntity temppivot,0,SteeringAngle#,0,False   
  TOKRB_SetRotation FLJointConnector,EntityPitch(temppivot),EntityYaw(temppivot),EntityRoll(temppivot)
  RotateEntity temppivot,TOKJOINT_GetFrameBPitch(FRSteering),TOKJOINT_GetFrameBYaw(FRSteering),TOKJOINT_GetFrameBRoll(FRSteering)
  TurnEntity temppivot,0,SteeringAngle#,0,False   
  TOKRB_SetRotation FRJointConnector,EntityPitch(temppivot),EntityYaw(temppivot),EntityRoll(temppivot)

; Acceleration

 If KeyDown(200) Then
  Torque#=300.0
 ElseIf KeyDown(208) Then
  Torque#=-300.0
 Else
  Torque#=Torque#*0.05
 EndIf

; Faking some kind of differential (For better steering)
   LWheelBoost#=1-SteeringAngle#*0.02
   RWheelBoost#=1+SteeringAngle#*0.02

  RotateEntity temppivot,TOKJOINT_GetFrameAPitch(RLAxle),TOKJOINT_GetFrameAYaw(RLAxle),TOKJOINT_GetFrameARoll(RLAxle)-90
  TFormVector Torque#*LWheelBoost#,0,0,temppivot,0  
  TOKRB_SetTorque RLWheel_RB,TFormedX#(),TFormedY#(),TFormedZ#()
  RotateEntity temppivot,TOKJOINT_GetFrameAPitch(RRAxle),TOKJOINT_GetFrameAYaw(RRAxle),TOKJOINT_GetFrameARoll(RRAxle)-90
  TFormVector Torque#*RWheelBoost#,0,0,temppivot,0  
  TOKRB_SetTorque RRWheel_RB,TFormedX#(),TFormedY#(),TFormedZ#()

  If KeyDown(57) Then
   TOKRB_SetForce2 Chassi_RB,0,1500,0,TOKRB_GetX#(Chassi_RB)+1,TOKRB_GetY#(Chassi_RB),TOKRB_GetZ#(Chassi_RB)
  Else
   TOKRB_SetForce2 Chassi_RB,0,0,0,0,0,0
  EndIf

	Next

 PositionEntity Chassi_Mesh,TOKRB_GetX(Chassi_RB),TOKRB_GetY(Chassi_RB),TOKRB_GetZ(Chassi_RB) 
 RotateEntity Chassi_Mesh,TOKRB_GetPitch(Chassi_RB),TOKRB_GetYaw(Chassi_RB),TOKRB_GetRoll(Chassi_RB),False
 PositionEntity RLWheel_Mesh,TOKRB_GetX(RLWheel_RB),TOKRB_GetY(RLWheel_RB),TOKRB_GetZ(RLWheel_RB) 
 RotateEntity RLWheel_Mesh,TOKRB_GetPitch(RLWheel_RB),TOKRB_GetYaw(RLWheel_RB),TOKRB_GetRoll(RLWheel_RB),False
 PositionEntity RRWheel_Mesh,TOKRB_GetX(RRLWheel_RB),TOKRB_GetY(RRWheel_RB),TOKRB_GetZ(RRWheel_RB) 
 RotateEntity RRWheel_Mesh,TOKRB_GetPitch(RRWheel_RB),TOKRB_GetYaw(RRWheel_RB),TOKRB_GetRoll(RRWheel_RB),False
 PositionEntity FLWheel_Mesh,TOKRB_GetX(FLWheel_RB),TOKRB_GetY(FLWheel_RB),TOKRB_GetZ(FLWheel_RB) 
 RotateEntity FLWheel_Mesh,TOKRB_GetPitch(FLWheel_RB),TOKRB_GetYaw(FLWheel_RB),TOKRB_GetRoll(FLWheel_RB),False
 PositionEntity FRWheel_Mesh,TOKRB_GetX(FRLWheel_RB),TOKRB_GetY(FRWheel_RB),TOKRB_GetZ(FRWheel_RB) 
 RotateEntity FRWheel_Mesh,TOKRB_GetPitch(FRWheel_RB),TOKRB_GetYaw(FRWheel_RB),TOKRB_GetRoll(FRWheel_RB),False

; RotateEntity camera,TOKRB_GetPitch(Chassi_RB),TOKRB_GetYaw(Chassi_RB),TOKRB_GetRoll(Chassi_RB),False
; PositionEntity camera,TOKRB_GetX(Chassi_RB),TOKRB_GetY(Chassi_RB),TOKRB_GetZ(Chassi_RB)
; MoveEntity camera,0,1,0.1
 PointEntity camera,Chassi_Mesh

	RenderWorld tween

Text 0,0,"Physics Time:"+TOKSIM_GetPhysicsTime()*1000.0+ " milliseconds"
Text 0,10,"Render Time:"+Str(elapsed)+ " milliseconds"
Text 0,20,"Left:  "+Str(LWheelBoost#)
Text 0,30,"Right:"+Str(RWheelBoost#)
	Flip False

Wend

TOKSIM_DestroySimulator()

End

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



BlitzSupport(Posted 2004) [#25]
Nice mod, Pongo. It'll take someone far smarter than me to fix the rollover thing though!


bradford6(Posted 2004) [#26]
try this one guys:

make sure you have Pongo's files in the same dir...
("track_fence.b3d") & ("mud_infield.b3d")



I put some interesting variables right at the top of the code

Press f1 for a 3rd person chase cam...
f2 changes the distance

; Thanks to Pongo for the Racetrack and Carmodel.

; play around with these values to tweak

chassi_mass# = 30
chassis_linear_damping# = 0.0001
chassis_angular_damping# = 0.1
wheel_linear_damping# = 0.0001
wheel_angular_damping# = 0.02
wheelmass# = 10
accel# = .1
top_torque# = 80
; ***************************************

Const FPS=90

Graphics3D 1024,768
SetBuffer BackBuffer()

WireFrame False

Global TOKS

Dim obj(100)
Dim rb(100)
camdistance# = 12

camera = CreateCamera()
PositionEntity camera,70,20,0
CameraZoom camera,2

TOKSIM_CreateSimulator(0,-15,0)

TOKSIM_SetMaterial 1,30.0,12.0 
TOKSIM_SetMaterial 2,10.0,10.0  

cubetex = create_cube_texture()

For columns = 1 To 4
	For rows = 1 To 4
	
		create_TOK_BOX(3,3,3,(columns*4)-55,(rows*3)+0.1,26,0.001,0.01,2.5,3,3,3,2.5,cubetex,"car")
	Next
Next


fence=LoadMesh("track_fence.b3d")
ScaleMesh fence,0.25,0.25,0.25


infield=LoadMesh("mud_infield.b3d")
ScaleMesh infield,0.25,0.25,0.25


Terrain = LoadMesh("oval_racetrack.b3d")
ScaleMesh Terrain,0.25,0.25,0.25

AddMesh terrain,infield
FreeEntity terrain

MakeTokCollider(infield)


;MakeTokCollider(Terrain)

;Ground = CreateCube()
;ScaleMesh Ground,0.5,0.5,0.5
;ScaleEntity Ground,300,10,300 
;PositionEntity Ground,0,-5,0
;EntityColor Ground,10,10,100
 
;ABGround = TOKAB_Create()
;geom = TOKAB_AddBox(ABGround,300,10,300)
;TOKGEOM_SetMaterialIndex geom,2
;TOKAB_SetPosition ABGround,0,-5,0

Jump = CreateCube()
ScaleMesh Jump,0.5,0.5,0.5
ScaleEntity Jump,15,15,15 
PositionEntity Jump,-45,-4.5,10
RotateEntity Jump,5,-90,-15
EntityColor Jump,30,130,30
 
ABJump = TOKAB_Create()
geom = TOKAB_AddBox(ABJump,15,15,15)
TOKGEOM_SetMaterialIndex geom,2
TOKAB_SetPosition ABJump,-45,-4.5,10
TOKAB_SetRotation ABJump,5,-90,-15

YOffset#=2.0

;Build Chassi

chassi_mass# = 40
chassis_linear_damping# = 0.0001
chassis_angular_damping# = 0.02

wheel_linear_damping# = 0.0001
wheel_angular_damping# = 0.02
wheelmass# = 2.0



Chassi_Mesh = LoadMesh("truck_body.b3d")
ScaleMesh Chassi_Mesh,0.3,0.3,0.3
RotateMesh Chassi_Mesh,0,180,0 
PositionMesh Chassi_Mesh,0,-1.5,0 

chassi_pivot = CreatePivot(chassi_mesh)
MoveEntity chassi_pivot,0,0,-camdistance#

Chassi_RB = TOKRB_Create()
TOKRB_AddBox Chassi_RB,2.0,1.3,4.0
TOKRB_SetMass Chassi_RB,chassi_mass#
TOKRB_SetBoxInertiaTensor Chassi_RB,1.5,2.0,3.0,chassi_mass#
TOKRB_SetLinearDamping Chassi_RB,chassis_linear_damping#
TOKRB_SetAngularDamping Chassi_RB,chassis_angular_damping#
TOKRB_SetPosition Chassi_RB,0,0.0+YOffset#,0

;Build RearLeft Wheel
RLWheel_Mesh = LoadMesh("truck_wheel.b3d")
ScaleMesh RLWheel_Mesh,0.32,0.32,0.32
RotateMesh RLWheel_Mesh,0,180,0 

RLWheel_RB = TOKRB_Create()
geom = TOKRB_AddSphere(RLWheel_RB,1.1)
TOKGEOM_SetMaterialIndex geom,1
TOKRB_SetMass RLWheel_RB,wheelmass#
TOKRB_SetSphereInertiaTensor RLWheel_RB,1.2,wheelmass#

TOKRB_SetPosition RLWheel_RB,-1.2,-0.7+YOffset#,-1.5 
TOKRB_SetLinearDamping RLWheel_RB,wheel_linear_damping#
TOKRB_SetAngularDamping RLWheel_RB,wheel_angular_damping#

;Build RearRight Wheel
RRWheel_Mesh = LoadMesh("truck_wheel.b3d")
ScaleMesh RRWheel_Mesh,0.32,0.32,0.32
RotateMesh RRWheel_Mesh,0,180,0 

RRWheel_RB = TOKRB_Create()
geom=TOKRB_AddSphere(RRWheel_RB,1.1)
TOKGEOM_SetMaterialIndex geom,1
TOKRB_SetMass RRWheel_RB,wheelmass#
TOKRB_SetSphereInertiaTensor RRWheel_RB,1.2,wheelmass#

TOKRB_SetPosition RRWheel_RB,1.2,-0.7+YOffset#,-1.5 
TOKRB_SetLinearDamping RRWheel_RB,wheel_linear_damping#
TOKRB_SetAngularDamping RRWheel_RB,wheel_angular_damping#

;Build FrontLeft Wheel
FLWheel_Mesh = LoadMesh("truck_wheel.b3d")
ScaleMesh FLWheel_Mesh,0.32,0.32,0.32
RotateMesh FLWheel_Mesh,0,180,0 

FLWheel_RB = TOKRB_Create()
geom=TOKRB_AddSphere(FLWheel_RB,1.1)
TOKGEOM_SetMaterialIndex geom,1
TOKRB_SetMass FLWheel_RB,wheelmass#
TOKRB_SetSphereInertiaTensor FLWheel_RB,1.2,wheelmass#

TOKRB_SetPosition FLWheel_RB,-1.2,-0.7+YOffset#,1.7 
TOKRB_SetLinearDamping FLWheel_RB,wheel_linear_damping#
TOKRB_SetAngularDamping FLWheel_RB,wheel_angular_damping#
TOKRB_CollideConnected FLWheel_RB,False

;Build FrontRight Wheel
FRWheel_Mesh = LoadMesh("truck_wheel.b3d")
ScaleMesh FRWheel_Mesh,0.32,0.32,0.32
RotateMesh FRWheel_Mesh,0,180,0 

FRWheel_RB = TOKRB_Create()
geom=TOKRB_AddSphere(FRWheel_RB,1.1)
TOKGEOM_SetMaterialIndex geom,1
TOKRB_SetMass FRWheel_RB,wheelmass#
TOKRB_SetSphereInertiaTensor FRWheel_RB,1.2,wheelmass#

TOKRB_SetPosition FRWheel_RB,1.2,-0.7+YOffset#,1.7 
TOKRB_SetLinearDamping FRWheel_RB,wheel_linear_damping#
TOKRB_SetAngularDamping FRWheel_RB,wheel_angular_damping#
TOKRB_CollideConnected FRWheel_RB,False

; Create Rear Axles
RLAxle = TOKJOINT_Create(2,RLWheel_RB,Chassi_RB)
TOKJOINT_SetType RLAxle,3 ; Hinge
TOKJOINT_SetPositionAndRotationWorld RLAxle,-1.2,-0.7+YOffset#,-1.5,0,0,90
TOKJOINT_Enable RLAxle,True 
TOKJOINT_SetDampingFactor RLAxle,0.5 
TOKJOINT_SetEpsilon RLAxle,0.0
TOKJOINT_SetIterations RLAxle,10  

RRAxle = TOKJOINT_Create(2,RRWheel_RB,Chassi_RB)
TOKJOINT_SetType RRAxle,3 ; Hinge
TOKJOINT_SetPositionAndRotationWorld RRAxle,1.2,-0.7+YOffset#,-1.5,0,0,90
TOKJOINT_Enable RRAxle,True 
TOKJOINT_SetDampingFactor RRAxle,0.5 
TOKJOINT_SetEpsilon RRAxle,0.0
TOKJOINT_SetIterations RRAxle,10  

; Create Steering Axles

FLJointConnector = TOKRB_Create()
TOKRB_SetPosition FLJointConnector,-1.2,-0.7+YOffset#,1.7
FLSteering = TOKJOINT_Create(2,FLJointConnector,Chassi_RB)
TOKJOINT_SetType FLSteering,3 ; Hinge
TOKJOINT_SetPositionAndRotationWorld FLSteering,-1.2,-0.7+YOffset#,1.7,0,0,0
TOKJOINT_Enable FLSteering,True 
TOKJOINT_SetLowerLimit FLSteering,-3.14*0.25 ; -45 Degrees
TOKJOINT_SetUpperLimit FLSteering,3.14*0.25 ; +45 Degrees
TOKJOINT_EnableLimit FLSteering,False 
;TOKJOINT_SetDampingFactor FLSteering,5.0
TOKJOINT_SetEpsilon FLSteering,0.0
TOKJOINT_SetIterations FLSteering,10  

FRJointConnector = TOKRB_Create()
TOKRB_SetPosition FRJointConnector,1.2,-0.7+YOffset#,1.7
FRSteering = TOKJOINT_Create(2,FRJointConnector,Chassi_RB)
TOKJOINT_SetType FRSteering,3 ; Hinge
TOKJOINT_SetPositionAndRotationWorld FRSteering,1.2,-0.7+YOffset#,1.7,0,0,0
TOKJOINT_Enable FRSteering,True 
TOKJOINT_SetLowerLimit FRSteering,-3.14*0.25 ; -45 Degrees
TOKJOINT_SetUpperLimit FRSteering,3.14*0.25 ; +45 Degrees
TOKJOINT_EnableLimit FRSteering,False
;TOKJOINT_SetDampingFactor FRSteering,5.0
TOKJOINT_SetEpsilon FRSteering,0.0
TOKJOINT_SetIterations FRSteering,10  

; Create Front Axles

FLAxle = TOKJOINT_Create(2,FLWheel_RB,FLJointConnector)
TOKJOINT_SetType FLAxle,3 ; Hinge
TOKJOINT_SetPositionAndRotationWorld FLAxle,-1.2,-0.7+YOffset#,1.7,0,0,90
TOKJOINT_Enable FLAxle,True 
TOKJOINT_SetDampingFactor FLAxle,0.5
TOKJOINT_SetEpsilon FLAxle,0.0
TOKJOINT_SetIterations FLAxle,10  

FRAxle = TOKJOINT_Create(2,FRWheel_RB,FRJointConnector)
TOKJOINT_SetType FRAxle,3 ; Hinge
TOKJOINT_SetPositionAndRotationWorld FRAxle,1.2,-0.7+YOffset#,1.7,0,0,90
TOKJOINT_Enable FRAxle,True 
TOKJOINT_SetDampingFactor FRAxle,0.5
TOKJOINT_SetEpsilon FRAxle,0.0
TOKJOINT_SetIterations FRAxle,10  

Centerpivot = CreatePivot()
light=CreateLight()
PositionEntity light,7,15,-5
PointEntity light,Centerpivot

period=1000/FPS
time=MilliSecs()-period

temppivot=CreatePivot()

; 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

; Steering

  If KeyDown(203) And SteeringAngle#<20 Then
   SteeringAngle#=SteeringAngle#+(((top_torque+9)-torque#) / 20)
  ElseIf KeyDown(205) And SteeringAngle#>-20 Then
   SteeringAngle#=SteeringAngle#-(((top_torque+9)-torque#) / 20)

  Else
   If SteeringAngle#>0 Then
     SteeringAngle#=SteeringAngle#*0.97
   ElseIf SteeringAngle#<0 Then
     SteeringAngle#=SteeringAngle#*0.97
   EndIf
  EndIf

  RotateEntity temppivot,TOKJOINT_GetFrameBPitch(FLSteering),TOKJOINT_GetFrameBYaw(FLSteering),TOKJOINT_GetFrameBRoll(FLSteering)
  TurnEntity temppivot,0,SteeringAngle#,0,False   
  TOKRB_SetRotation FLJointConnector,EntityPitch(temppivot),EntityYaw(temppivot),EntityRoll(temppivot)
  RotateEntity temppivot,TOKJOINT_GetFrameBPitch(FRSteering),TOKJOINT_GetFrameBYaw(FRSteering),TOKJOINT_GetFrameBRoll(FRSteering)
  TurnEntity temppivot,0,SteeringAngle#,0,False   
  TOKRB_SetRotation FRJointConnector,EntityPitch(temppivot),EntityYaw(temppivot),EntityRoll(temppivot)

; Acceleration




 If KeyDown(200) Then
  Torque#=torque# + accel#
	If torque# < 0 Then torque# = 0
	If torque# > top_torque# Then torque# = top_torque#
 ElseIf KeyDown(208) Then
  Torque#=torque - accel#
	If torque# < -40 Then torque# = -40
	If torque# > 0 Then torque# = 0

 Else
  Torque#=Torque#*0.997
 EndIf

; Faking some kind of differential (For better steering)
   LWheelBoost#=1-SteeringAngle#*0.02
   RWheelBoost#=1+SteeringAngle#*0.02

  RotateEntity temppivot,TOKJOINT_GetFrameAPitch(RLAxle),TOKJOINT_GetFrameAYaw(RLAxle),TOKJOINT_GetFrameARoll(RLAxle)-90
  TFormVector Torque#*LWheelBoost#,0,0,temppivot,0  
  TOKRB_SetTorque RLWheel_RB,TFormedX#(),TFormedY#(),TFormedZ#()
  RotateEntity temppivot,TOKJOINT_GetFrameAPitch(RRAxle),TOKJOINT_GetFrameAYaw(RRAxle),TOKJOINT_GetFrameARoll(RRAxle)-90
  TFormVector Torque#*RWheelBoost#,0,0,temppivot,0  
  TOKRB_SetTorque RRWheel_RB,TFormedX#(),TFormedY#(),TFormedZ#()

  If KeyDown(57) Then
   TOKRB_SetForce2 Chassi_RB,0,1500,0,TOKRB_GetX#(Chassi_RB)+1,TOKRB_GetY#(Chassi_RB),TOKRB_GetZ#(Chassi_RB)
  Else
   TOKRB_SetForce2 Chassi_RB,0,0,0,0,0,0
  EndIf

	Next

 PositionEntity Chassi_Mesh,TOKRB_GetX(Chassi_RB),TOKRB_GetY(Chassi_RB),TOKRB_GetZ(Chassi_RB) 
 RotateEntity Chassi_Mesh,TOKRB_GetPitch(Chassi_RB),TOKRB_GetYaw(Chassi_RB),TOKRB_GetRoll(Chassi_RB),False
 PositionEntity RLWheel_Mesh,TOKRB_GetX(RLWheel_RB),TOKRB_GetY(RLWheel_RB),TOKRB_GetZ(RLWheel_RB) 
 RotateEntity RLWheel_Mesh,TOKRB_GetPitch(RLWheel_RB),TOKRB_GetYaw(RLWheel_RB),TOKRB_GetRoll(RLWheel_RB),False
 PositionEntity RRWheel_Mesh,TOKRB_GetX(RRLWheel_RB),TOKRB_GetY(RRWheel_RB),TOKRB_GetZ(RRWheel_RB) 
 RotateEntity RRWheel_Mesh,TOKRB_GetPitch(RRWheel_RB),TOKRB_GetYaw(RRWheel_RB),TOKRB_GetRoll(RRWheel_RB),False
 PositionEntity FLWheel_Mesh,TOKRB_GetX(FLWheel_RB),TOKRB_GetY(FLWheel_RB),TOKRB_GetZ(FLWheel_RB) 
 RotateEntity FLWheel_Mesh,TOKRB_GetPitch(FLWheel_RB),TOKRB_GetYaw(FLWheel_RB),TOKRB_GetRoll(FLWheel_RB),False
 PositionEntity FRWheel_Mesh,TOKRB_GetX(FRLWheel_RB),TOKRB_GetY(FRWheel_RB),TOKRB_GetZ(FRWheel_RB) 
 RotateEntity FRWheel_Mesh,TOKRB_GetPitch(FRWheel_RB),TOKRB_GetYaw(FRWheel_RB),TOKRB_GetRoll(FRWheel_RB),False

; RotateEntity camera,TOKRB_GetPitch(Chassi_RB),TOKRB_GetYaw(Chassi_RB),TOKRB_GetRoll(Chassi_RB),False
; PositionEntity camera,TOKRB_GetX(Chassi_RB),TOKRB_GetY(Chassi_RB),TOKRB_GetZ(Chassi_RB)
; MoveEntity camera,0,1,0.1
 ;PointEntity camera,Chassi_Mesh

camdist# = 2.0
camhgt# = 4
camspd# = 20

If KeyDown(60)
	cam1 = (1 - cam1)
	If cam1 = 0
		MoveEntity chassi_pivot,0,0,10
		camspd# = 30
	EndIf
	If cam1 = 1
		MoveEntity chassi_pivot,0,0,-10
		camspd# = 80

	EndIf

EndIf
 
If KeyDown(59) 
 freecam = (1 - freecam)
	Repeat : Until KeyDown(59) = 0
EndIf	
If freecam = 0
		PointEntity camera,Chassi_Mesh
EndIf
If freecam = 1
		smoothcam(camera,chassi_pivot,chassi_mesh,camspd#,camhgt#)
EndIf
For i=1 To TOKS
		 ;If TOKRB_IsIdle(rb(i)) Then
		 ; EntityAlpha obj(i),0.5
		 ;Else
		 ; EntityAlpha obj(i),1.0
		 ; TOKRB_Active(rb(i),True)
		
		 ;EndIf
		 
		 If EntityName(obj(i)) = "ball"
			; do stuff
		 EndIf
		
		 PositionEntity obj(i),TOKRB_GetX#(rb(i)),TOKRB_GetY#(rb(i)),TOKRB_GetZ#(rb(i)) 
		 RotateEntity obj(i),TOKRB_GetPitch#(rb(i)),TOKRB_GetYaw#(rb(i)),TOKRB_GetRoll#(rb(i)),False
Next

	RenderWorld tween
	
Color 0,0,0 : Rect 0,0,200,90
Color 255,255,0
Text 0,0,"Physics Time:"+TOKSIM_GetPhysicsTime()*1000.0+ " ms"
Text 0,10,"Render Time:"+Str(elapsed)+ " ms"
Text 0,20,"Left:  "+Str(LWheelBoost#)
Text 0,30,"Right:"+Str(RWheelBoost#)
Text 0,40,"torque:"+Str(torque#)
Text 0,50,"cam y :"+Str(EntityY(camera))

If freecam = 0 Then nextcam$ = "Chase Cam"
If freecam = 1 Then nextcam$ = "Fixed Cam"
Text 0,60,"F1 => "+nextcam$
	Flip False

Wend

TOKSIM_DestroySimulator()

End

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 smoothcam(cam,pivot,target,camspeed#,camheight#)


	curx#=EntityX(cam)
	curz#=EntityZ(cam)
	cury#=EntityY(cam)
	destx#=EntityX(pivot,True)
	destz#=EntityZ(pivot,True)
	desty#=EntityY(pivot,True)+camheight#

	
		curx#=curx#+((destx#-curx#)/camspeed#);+ camdistance#
		curz#=curz#+((destz#-curz#)/camspeed#);+ camdistance#
		cury#=cury#+((desty#-cury#)/camspeed#/3);+ camdistance#

	;cury#=EntityY(target)+camheight#

	PositionEntity cam,curx#,cury,curz#
	
	PointEntity cam,target
End Function

Function create_TOK_BOX(xs#,ys#,zs#,xp#,yp#,zp#,damp#,angdamp#,mass#,iw#,ih#,id#,imass#,texture,name$)

			TOKS = TOKS+1
			;If TOKS>ENTS 
				;TOKS = ENTS
				;Return
			;EndIf
			obj(TOKS) = CreateCube()
			NameEntity obj(toks),name$
			ScaleEntity obj(TOKS),xs#/2,ys#/2,zs#/2
			EntityPickMode obj(TOKS),2
			EntityTexture obj(TOKS),texture
			rb(TOKS) = TOKRB_Create()
			TOKRB_SetSleepingParameter(rb(TOKS),-100)
			TOKRB_AddBox rb(TOKS),xs#,ys#,zs#
			TOKRB_SetPosition(rb(TOKS),xp#,yp#,zp#)
			TOKRB_SetLinearDamping rb(TOKS),damp#
			TOKRB_SetAngularDamping rb(TOKS),angdamp# 

			TOKRB_SetMass rb(TOKS),mass#
			TOKRB_SetBoxInertiaTensor rb(TOKS),iw#,ih#,id#,imass# 
			
			

End Function

Function create_cube_texture()
	tex = CreateTexture(64,64)
	ScaleTexture tex,.5,.5
	SetBuffer TextureBuffer(tex)
		Color 20,20,200
		Rect 0,0,64,64
		Color 255,255,255
		Rect 0,0,32,32
		Rect 32,32,64,64
		Color 0,0,0
		Rect 0,0,64,64,0
	SetBuffer BackBuffer()
	Return tex
	

End Function





Pongo(Posted 2004) [#27]
cool,... you beat me to it,... I guess I'll post this anyways,... sorry to fill the thread with this stuff, but I think it's working out pretty neat and wanted to share.

By the way, I race RC cars, and that is heavily influencing my adjustments here. Might explain why all my stuff is moving at faster speeds. I added Joystick control into this version (might need to tweak for your own joystick) I have one that is like an RC controller with trigger for gas/brake and a small wheel,... feels almost perfect with that.

As before, I take no credit for the code,... this is just a hack cut and paste from some other demos with some parameter changes. This version does not require the extra files either, so it will work with the ones included in the .4 wrapper.


; Thanks to Pongo for the Racetrack and Carmodel.

Const FPS=90

Graphics3D 1024,768
SetBuffer BackBuffer()

WireFrame False

camera = CreateCamera()
PositionEntity camera,70,30,0
CameraZoom camera,2

TOKSIM_CreateSimulator(0,-45,0)

TOKSIM_SetMaterial 1,30.0,12.0 
TOKSIM_SetMaterial 2,10.0,10.0 

;fence=LoadMesh("track_fence.b3d")
;ScaleMesh fence,0.25,0.25,0.25

Terrain = LoadMesh("oval_racetrack.b3d")
ScaleMesh Terrain,0.25,0.25,0.25

MakeTokCollider(terrain)

Ground = CreateCube()
ScaleMesh Ground,0.5,0.5,0.5
ScaleEntity Ground,300,10,300 
PositionEntity Ground,0,-5,0
EntityColor Ground,10,100,10
 
ABGround = TOKAB_Create()
geom = TOKAB_AddBox(ABGround,300,10,300)
TOKGEOM_SetMaterialIndex geom,2
TOKAB_SetPosition ABGround,0,-5,0

;::::::::::::::::::::::::::: added this block from other demo
Global ents= 40

Dim obj(ents)
Dim rb(ents)

For i=1 To ents ; entity count
rot#=rot#+8.2

 ; change the line below to 1,3 to include "cylinders".
 ; I render them as cylinders but the rigidbody is really a capsule, so
 ; the bodies will behave like capsules and not like cylinders.

 nr=Rnd(1,3)		
 If nr=1 Then
  obj(i) = CreateCube()
  ScaleEntity obj(i),1,1,1 
  rb(i) = TOKRB_Create()
  TOKRB_AddBox rb(i),2.0,2.0,2.0
  TOKRB_SetPosition rb(i),0,i*2,0
  TOKRB_SetLinearDamping rb(i),0.001
  TOKRB_SetAngularDamping rb(i),0.02 	
  TOKRB_SetMass rb(i),10.0
  TOKRB_SetBoxInertiaTensor rb(i),2.0,2.0,2.0,2.0  
 ElseIf nr=2 
  obj(i) = CreateSphere()
  rb(i) = TOKRB_Create()
  TOKRB_AddSphere rb(i),2
  TOKRB_SetPosition rb(i),0,i*2,0
  TOKRB_SetLinearDamping rb(i),0.001 
  TOKRB_SetAngularDamping rb(i),0.02 
  TOKRB_SetMass rb(i),3.0
  TOKRB_SetSphereInertiaTensor rb(i),2,1.5 
 ElseIf nr=3 
  obj(i) = CreateCylinder()
  rb(i) = TOKRB_Create()
  TOKRB_AddCylinder rb(i),2.0,1.0
  TOKRB_SetPosition rb(i),0,i*2,0
  TOKRB_SetLinearDamping rb(i),0.001 
  TOKRB_SetAngularDamping rb(i),0.01 
  TOKRB_SetMass rb(i),2.0
  TOKRB_SetCylinderInertiaTensor rb(i),2.0,1.0,2.0  
 EndIf

 EntityColor obj(i),Rnd(100,230),Rnd(100,230),Rnd(100,230) 

Next

;;;;;;;;;;;;;;;;;;;;;;;;;;;;


Jump = CreateCube()
ScaleMesh Jump,0.5,0.5,0.5
ScaleEntity Jump,10,10,10 
PositionEntity Jump,0,-4.5,20
RotateEntity Jump,0,0,-25
EntityColor Jump,30,130,30
 
ABJump = TOKAB_Create()
geom = TOKAB_AddBox(ABJump,10,10,10)
TOKGEOM_SetMaterialIndex geom,2
TOKAB_SetPosition ABJump,0,-4.5,20
TOKAB_SetRotation ABJump,0,0,-25

YOffset#=2.0

;Build Chassi
Chassi_Mesh = LoadMesh("truck_body.b3d")
ScaleMesh Chassi_Mesh,0.3,0.3,0.3
RotateMesh Chassi_Mesh,0,180,0 
PositionMesh Chassi_Mesh,0,-1.5,0 

Chassi_RB = TOKRB_Create()
TOKRB_AddBox Chassi_RB,2.0,1.3,4.0
TOKRB_SetMass Chassi_RB,40.0
TOKRB_SetBoxInertiaTensor Chassi_RB,1.5,1.0,3.0,50.0 
TOKRB_SetLinearDamping Chassi_RB,0.003
TOKRB_SetAngularDamping Chassi_RB,0.005
TOKRB_SetPosition Chassi_RB,0,0.0+YOffset#,0

;Build RearLeft Wheel
RLWheel_Mesh = LoadMesh("truck_wheel.b3d")
ScaleMesh RLWheel_Mesh,0.32,0.32,0.32
RotateMesh RLWheel_Mesh,0,180,0 

RLWheel_RB = TOKRB_Create()
geom = TOKRB_AddSphere(RLWheel_RB,1.1)
TOKGEOM_SetMaterialIndex geom,1
TOKRB_SetMass RLWheel_RB,3.0
TOKRB_SetSphereInertiaTensor RLWheel_RB,1.2,1.5 
TOKRB_SetPosition RLWheel_RB,-1.2,-0.7+YOffset#,-1.5 
TOKRB_SetLinearDamping RLWheel_RB,0.001
TOKRB_SetAngularDamping RLWheel_RB,0.02

;Build RearRight Wheel
RRWheel_Mesh = LoadMesh("truck_wheel.b3d")
ScaleMesh RRWheel_Mesh,0.32,0.32,0.32
RotateMesh RRWheel_Mesh,0,180,0 

RRWheel_RB = TOKRB_Create()
geom=TOKRB_AddSphere(RRWheel_RB,1.1)
TOKGEOM_SetMaterialIndex geom,1
TOKRB_SetMass RRWheel_RB,3.0
TOKRB_SetSphereInertiaTensor RRWheel_RB,1.2,1.5 
TOKRB_SetPosition RRWheel_RB,1.2,-0.7+YOffset#,-1.5 
TOKRB_SetLinearDamping RRWheel_RB,0.001
TOKRB_SetAngularDamping RRWheel_RB,0.02

;Build FrontLeft Wheel
FLWheel_Mesh = LoadMesh("truck_wheel.b3d")
ScaleMesh FLWheel_Mesh,0.32,0.32,0.32
RotateMesh FLWheel_Mesh,0,180,0 

FLWheel_RB = TOKRB_Create()
geom=TOKRB_AddSphere(FLWheel_RB,1.1)
TOKGEOM_SetMaterialIndex geom,1
TOKRB_SetMass FLWheel_RB,3.0
TOKRB_SetSphereInertiaTensor FLWheel_RB,1.2,1.5 
TOKRB_SetPosition FLWheel_RB,-1.2,-0.7+YOffset#,1.7 
TOKRB_SetLinearDamping FLWheel_RB,0.001
TOKRB_SetAngularDamping FLWheel_RB,0.02
TOKRB_CollideConnected FLWheel_RB,False

;Build FrontRight Wheel
FRWheel_Mesh = LoadMesh("truck_wheel.b3d")
ScaleMesh FRWheel_Mesh,0.32,0.32,0.32
RotateMesh FRWheel_Mesh,0,180,0 

FRWheel_RB = TOKRB_Create()
geom=TOKRB_AddSphere(FRWheel_RB,1.1)
TOKGEOM_SetMaterialIndex geom,1
TOKRB_SetMass FRWheel_RB,3.0
TOKRB_SetSphereInertiaTensor FRWheel_RB,1.2,1.5 
TOKRB_SetPosition FRWheel_RB,1.2,-0.7+YOffset#,1.7 
TOKRB_SetLinearDamping FRWheel_RB,0.001
TOKRB_SetAngularDamping FRWheel_RB,0.02
TOKRB_CollideConnected FRWheel_RB,False

; Create Rear Axles
RLAxle = TOKJOINT_Create(2,RLWheel_RB,Chassi_RB)
TOKJOINT_SetType RLAxle,3 ; Hinge
TOKJOINT_SetPositionAndRotationWorld RLAxle,-1.2,-0.7+YOffset#,-1.5,0,0,90
TOKJOINT_Enable RLAxle,True 
TOKJOINT_SetDampingFactor RLAxle,0.5 
TOKJOINT_SetEpsilon RLAxle,0.0
TOKJOINT_SetIterations RLAxle,10  

RRAxle = TOKJOINT_Create(2,RRWheel_RB,Chassi_RB)
TOKJOINT_SetType RRAxle,3 ; Hinge
TOKJOINT_SetPositionAndRotationWorld RRAxle,1.2,-0.7+YOffset#,-1.5,0,0,90
TOKJOINT_Enable RRAxle,True 
TOKJOINT_SetDampingFactor RRAxle,0.5 
TOKJOINT_SetEpsilon RRAxle,0.0
TOKJOINT_SetIterations RRAxle,10  

; Create Steering Axles

FLJointConnector = TOKRB_Create()
TOKRB_SetPosition FLJointConnector,-1.2,-0.7+YOffset#,1.7
FLSteering = TOKJOINT_Create(2,FLJointConnector,Chassi_RB)
TOKJOINT_SetType FLSteering,3 ; Hinge
TOKJOINT_SetPositionAndRotationWorld FLSteering,-1.2,-0.7+YOffset#,1.7,0,0,0
TOKJOINT_Enable FLSteering,True 
TOKJOINT_SetLowerLimit FLSteering,-3.14*0.25 ; -45 Degrees
TOKJOINT_SetUpperLimit FLSteering,3.14*0.25 ; +45 Degrees
TOKJOINT_EnableLimit FLSteering,False 
;TOKJOINT_SetDampingFactor FLSteering,5.0
TOKJOINT_SetEpsilon FLSteering,0.0
TOKJOINT_SetIterations FLSteering,10  

FRJointConnector = TOKRB_Create()
TOKRB_SetPosition FRJointConnector,1.2,-0.7+YOffset#,1.7
FRSteering = TOKJOINT_Create(2,FRJointConnector,Chassi_RB)
TOKJOINT_SetType FRSteering,3 ; Hinge
TOKJOINT_SetPositionAndRotationWorld FRSteering,1.2,-0.7+YOffset#,1.7,0,0,0
TOKJOINT_Enable FRSteering,True 
TOKJOINT_SetLowerLimit FRSteering,-3.14*0.25 ; -45 Degrees
TOKJOINT_SetUpperLimit FRSteering,3.14*0.25 ; +45 Degrees
TOKJOINT_EnableLimit FRSteering,False
;TOKJOINT_SetDampingFactor FRSteering,5.0
TOKJOINT_SetEpsilon FRSteering,0.0
TOKJOINT_SetIterations FRSteering,10  

; Create Front Axles

FLAxle = TOKJOINT_Create(2,FLWheel_RB,FLJointConnector)
TOKJOINT_SetType FLAxle,3 ; Hinge
TOKJOINT_SetPositionAndRotationWorld FLAxle,-1.2,-0.7+YOffset#,1.7,0,0,90
TOKJOINT_Enable FLAxle,True 
TOKJOINT_SetDampingFactor FLAxle,0.5
TOKJOINT_SetEpsilon FLAxle,0.0
TOKJOINT_SetIterations FLAxle,10  

FRAxle = TOKJOINT_Create(2,FRWheel_RB,FRJointConnector)
TOKJOINT_SetType FRAxle,3 ; Hinge
TOKJOINT_SetPositionAndRotationWorld FRAxle,1.2,-0.7+YOffset#,1.7,0,0,90
TOKJOINT_Enable FRAxle,True 
TOKJOINT_SetDampingFactor FRAxle,0.5
TOKJOINT_SetEpsilon FRAxle,0.0
TOKJOINT_SetIterations FRAxle,10  

Centerpivot = CreatePivot()
light=CreateLight(2)
PositionEntity light,300,700,1000
PointEntity light,Centerpivot


period=1000/FPS
time=MilliSecs()-period

temppivot=CreatePivot()

; MainLoop
While Not KeyHit(1)

; Not sure wether to put this here or inside the for/next above...
For i=1 To ents
; If TOKRB_IsIdle(rb(i)) Then
;  EntityAlpha obj(i),0.5
; Else
;  EntityAlpha obj(i),1.0
; EndIf
 PositionEntity obj(i),TOKRB_GetX#(rb(i)),TOKRB_GetY#(rb(i)),TOKRB_GetZ#(rb(i)) 
 RotateEntity obj(i),TOKRB_GetPitch#(rb(i)),TOKRB_GetYaw#(rb(i)),TOKRB_GetRoll#(rb(i)),False
Next

	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

; Steering

  If KeyDown(203) And SteeringAngle#<18 Then
   SteeringAngle#=SteeringAngle#+1
  ElseIf KeyDown(205) And SteeringAngle#>-18 Then
   SteeringAngle#=SteeringAngle#-1
  ElseIf JoyX()>.1 Or JoyX()<-.1 ;joystick control added by Pongo
	steeringangle#=-JoyX()*25

 Else
   If SteeringAngle#>0 Then
     SteeringAngle#=SteeringAngle#-0.5
   ElseIf SteeringAngle#<0 Then
     SteeringAngle#=SteeringAngle#+0.5
   EndIf
  EndIf

  RotateEntity temppivot,TOKJOINT_GetFrameBPitch(FLSteering),TOKJOINT_GetFrameBYaw(FLSteering),TOKJOINT_GetFrameBRoll(FLSteering)
  TurnEntity temppivot,0,SteeringAngle#,0,False   
  TOKRB_SetRotation FLJointConnector,EntityPitch(temppivot),EntityYaw(temppivot),EntityRoll(temppivot)
  RotateEntity temppivot,TOKJOINT_GetFrameBPitch(FRSteering),TOKJOINT_GetFrameBYaw(FRSteering),TOKJOINT_GetFrameBRoll(FRSteering)
  TurnEntity temppivot,0,SteeringAngle#,0,False   
  TOKRB_SetRotation FRJointConnector,EntityPitch(temppivot),EntityYaw(temppivot),EntityRoll(temppivot)

; Acceleration

 If JoyY()>.1 Or JoyY()<-.1 ;joystick control by Pongo
	torque#=-JoyY()*300
 ElseIf KeyDown(200) Or JoyDown(2) Then
  Torque#=300.0
 ElseIf KeyDown(208) Or JoyDown(1) Then
  Torque#=-300.0

 Else
  Torque#=Torque#*0.05
 EndIf



; Faking some kind of differential (For better steering)
   LWheelBoost#=1-SteeringAngle#*0.02
   RWheelBoost#=1+SteeringAngle#*0.02

  RotateEntity temppivot,TOKJOINT_GetFrameAPitch(RLAxle),TOKJOINT_GetFrameAYaw(RLAxle),TOKJOINT_GetFrameARoll(RLAxle)-90
  TFormVector Torque#*LWheelBoost#,0,0,temppivot,0  
  TOKRB_SetTorque RLWheel_RB,TFormedX#(),TFormedY#(),TFormedZ#()
  RotateEntity temppivot,TOKJOINT_GetFrameAPitch(RRAxle),TOKJOINT_GetFrameAYaw(RRAxle),TOKJOINT_GetFrameARoll(RRAxle)-90
  TFormVector Torque#*RWheelBoost#,0,0,temppivot,0  
  TOKRB_SetTorque RRWheel_RB,TFormedX#(),TFormedY#(),TFormedZ#()

  If KeyDown(57) Then
   TOKRB_SetForce2 Chassi_RB,0,2000,0,TOKRB_GetX#(Chassi_RB)+1,TOKRB_GetY#(Chassi_RB),TOKRB_GetZ#(Chassi_RB)
  Else
   TOKRB_SetForce2 Chassi_RB,0,0,0,0,0,0
  EndIf

	Next

 PositionEntity Chassi_Mesh,TOKRB_GetX(Chassi_RB),TOKRB_GetY(Chassi_RB),TOKRB_GetZ(Chassi_RB) 
 RotateEntity Chassi_Mesh,TOKRB_GetPitch(Chassi_RB),TOKRB_GetYaw(Chassi_RB),TOKRB_GetRoll(Chassi_RB),False
 PositionEntity RLWheel_Mesh,TOKRB_GetX(RLWheel_RB),TOKRB_GetY(RLWheel_RB),TOKRB_GetZ(RLWheel_RB) 
 RotateEntity RLWheel_Mesh,TOKRB_GetPitch(RLWheel_RB),TOKRB_GetYaw(RLWheel_RB),TOKRB_GetRoll(RLWheel_RB),False
 PositionEntity RRWheel_Mesh,TOKRB_GetX(RRLWheel_RB),TOKRB_GetY(RRWheel_RB),TOKRB_GetZ(RRWheel_RB) 
 RotateEntity RRWheel_Mesh,TOKRB_GetPitch(RRWheel_RB),TOKRB_GetYaw(RRWheel_RB),TOKRB_GetRoll(RRWheel_RB),False
 PositionEntity FLWheel_Mesh,TOKRB_GetX(FLWheel_RB),TOKRB_GetY(FLWheel_RB),TOKRB_GetZ(FLWheel_RB) 
 RotateEntity FLWheel_Mesh,TOKRB_GetPitch(FLWheel_RB),TOKRB_GetYaw(FLWheel_RB),TOKRB_GetRoll(FLWheel_RB),False
 PositionEntity FRWheel_Mesh,TOKRB_GetX(FRLWheel_RB),TOKRB_GetY(FRWheel_RB),TOKRB_GetZ(FRWheel_RB) 
 RotateEntity FRWheel_Mesh,TOKRB_GetPitch(FRWheel_RB),TOKRB_GetYaw(FRWheel_RB),TOKRB_GetRoll(FRWheel_RB),False

; RotateEntity camera,TOKRB_GetPitch(Chassi_RB),TOKRB_GetYaw(Chassi_RB),TOKRB_GetRoll(Chassi_RB),False
; PositionEntity camera,TOKRB_GetX(Chassi_RB),TOKRB_GetY(Chassi_RB),TOKRB_GetZ(Chassi_RB)
; MoveEntity camera,0,1,0.1
 PointEntity camera,Chassi_Mesh

	RenderWorld tween

Text 0,0,"Physics Time:"+TOKSIM_GetPhysicsTime()*1000.0+ " milliseconds"
Text 0,10,"Render Time:"+Str(elapsed)+ " milliseconds"
Text 0,20,"Left:  "+Str(LWheelBoost#)
Text 0,30,"Right:"+Str(RWheelBoost#)
	Flip False

Wend

TOKSIM_DestroySimulator()

End

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



bradford6(Posted 2004) [#28]
Hey pongo, that'sgetting better. keep posting. no worries!

We have collectivley come up with some really cool stuff.

I am working on some spring/damping stuff for more realistic (fun) suspension.


Ice9(Posted 2004) [#29]
LOL That's great Pongo


BlitzSupport(Posted 2004) [#30]
Yeah, nice. Looking forward to the suspension stuff, Bill.

It would be so cool, once you guys have figured out the hard stuff and got the best possible control, to have something like c.Car = CreateCar (body, wheel1, wheel2, wheel3, wheel4, etc) and UpdateCar (c.Car) or similar... plus maybe some functions to modify individual .Car parameters (suspension strength/height, max torque, wheel friction, etc)? I'll probably have a go at wrapping it in this way once you brainiacs have figured out the best control methods!


EOF(Posted 2004) [#31]
How about a 'Stunt Car Racer' feel. That game was just fab.
All that bouncing, creaking, and groaning of the car as it leaped around the tracks.
It was just great fun hammering the car up a ramp then waiting like 10 seconds for the vehicle to land. Only to find you have completely overshot the end of the track :-/



BlitzSupport(Posted 2004) [#32]
Mmm, Stunt Car Racer...


Tracer(Posted 2004) [#33]
Yeeeaahh.. i'd love to make a Stunt Car Racer type game!


BTW.. it could be nice to have a special "Tokamak Source Codes" bit in the code archives.. that makes it a LOT easier to find stuff than having to dig through three threads worth of talk and code!

Tracer


Mark Judd(Posted 2004) [#34]
If I remember correctly, one of the clever things about SCR was the fact that you didn't have as much control over the car as you thought you had.

True, you had complete control over its speed, so whether you made a jump or made a crater was entirely up to you, but the steering was different.

There was an invisible guiding hand, ensuring that, unless you steered violently the car would try and stay on the track. I think this was because if the physics etc were 100% realistic the game would be next to impossible.

I play Grand Prix Legends, excellent car physics, fantastic third party tracks.
Recently some guy has emulated one of the SCR tracks (little ramp, i think), but you can't play it.

Imagine taking off on a jump, the car is not exactly straight, TOKAMAK does its stuff and you gracefully rotate through 270 degrees as the car flies through the air, until you land (perhaps on the track) but facing the wrong way, or sideways on. You get the picture.

My point being, with SCR (one of the greatest racing games ever IMHO) i think the appeal lies in the clever control system, coupled with physics applied in moderation. To do a modern version i think this would be the most important point, rather than throwing TOKAMAK at the whole thing.

/climbs down from soap box.

Funky Frank


EOF(Posted 2004) [#35]
Bang on Frank. I played SCR a lot. Yes, the steering was actually very simple. You basically nudged the car to the left/right around the track to keep it centered as much as possible.

Can we have a Physics Archive or a Tokamak section?


AbbaRue(Posted 2004) [#36]
Has anyone tried makeing a pool table demo yet?


AbbaRue(Posted 2004) [#37]
Maybe the archives should wait for the final release of the interface.
Then we won't have to modify the code.
I hope the interface stablizes soon, so we don't have to keep modifying preveous demos, to work with the new interface.
Has anyone thought of maybe writing a list of alias names for the commands that is only 4 or 5 letters long.
Makes for shorter lines of code. And less typeing too.


Ricky Smith(Posted 2004) [#38]

Has anyone thought of maybe writing a list of alias names for the commands that is only 4 or 5 letters long.
Makes for shorter lines of code. And less typeing too.



You can always change the function names by editing the .decls file which is, in effect, a list of alias function names - However I like the longer descriptive function names and wouldn't want to make my code less readable using abbreviations even if it means typing more.
I find Ctrl+C and Ctrl+V very useful too ! :)


AbbaRue(Posted 2004) [#39]
I know I can modify the .decls file but if someone writes a standard set of short aliases then it could be included with the interface and everyone would have a choice of the long name or the shortened name. And any demos exchanged would work without modifications.
Some commands are over 20 characters long.


bradford6(Posted 2004) [#40]
once the .dll gets to version 1.0, we could petition sweenie to create shorter names.

Why don't you come up with a naming convention that is concise, yet makes sense and is esy to remember.

TK_J_
TK_RB_
TK_AB_
TK_SIM_

i really don't mind longish names, I like clarity and readability rather that typing speed:

Python is better thatn perl in this regard.


Pongo(Posted 2004) [#41]
I personally vote no to abbreviated names. I like the long descriptive names now and would not want to lose that. I guess if it was done in a way where either syntax could be used, then it would be fine. I usually have to hunt for syntax anyways, so for me it's as easy as copy/paste, and having descriptive names lets me find what I'm looking for easier.


Sweenie(Posted 2004) [#42]
I the .declsfile allows it I guess abbreviated names could be added at the end or a second declsfile could be created.


bradford6(Posted 2004) [#43]
blitz IDE could take a cue from *nix and allow <tab> to finish commands

TOK<tab> could fire a pop-up window that allows you to scroll to the correct command


Rob(Posted 2004) [#44]
The names are fine IMHO. Whats needed is a comprehensive help system when you press F1 over a command. TIA to whoever wants to attempt it.


EOF(Posted 2004) [#45]
Whats needed is a comprehensive help system when you press F1 over a command
I did that in SpriteControl.
Here's a rundown on how to achieve the F1*2 command help:

a) Navigate to Blitz3D > help > commands > 2d_commands
Modify any of the *.htm files but save the modified file using the SAME NAME as your command name (with an *.htm extension).

b) repeat the process until you have a set of new commands.

c) Re-launch Blitz3D and F1*2 over you command to access the help file.


RepeatUntil(Posted 2004) [#46]
This is done automatically in Cod2Doc! The only thing is that Cod2Doc is not able (for now) to document directly a .decls file. But this is very easily done inside a .bb file like this:
; Creates the main simulator of Tokamak
; gravityX = the gravity along the x axis
; gravityY = the gravity along the y axis
; gravityZ = the gravity along the z axis
Function TOKSIM_CreateSimulator(gravityX#, gravityY#, gravityZ#)
End Function

; Creates a rigid body
; return = handle of the rigid body
Function TOKRB_Create()
End Function

; Add a box to a rigid body
; rigidBody = handle of the rigid body
; width = width of the box
; height = height of the box
; depth = depth of the box
; return = handle of the geometry (used for friction and restitution
Function TOKRB_AddBox(rigidBody, width#, height#, depth#)
End Function

Then, with Cod2Doc, you treat this .bb file. Put the option "functions only" + "highlight functions + quick help F1". And that's it -> Cod2Doc has automatically created the help files and put them into the Blitz folder.
(one thing to do is to erase the decls file created by Cod2Doc, as this one will conflict with the tokamak.decls file)

I put the result of this simple file on my web page:
http://repeatuntil.free.fr/tok/indexFunctions.html
Nice, no?? And that's a simple example, you could do more sophisticated... You can change easily the style too...
Hoping it gives you good idea ;)


bradford6(Posted 2004) [#47]
lets thank Sweenie again for this awesome piece of work. It always amazes me when someone puts in a HUGE amount of time, effort and dedication in a project and then freely shares it with the community.

Thank you, Sweenie!


Sweenie(Posted 2004) [#48]
I only created the wrapper, but the Tokamakteam put together a whole physicssystem and shared it for free, that amazes me.

Anyway, I experimented with springs last night and came up with some very funky suspension.
Very unstable and requires alot of jointiterations to keep it from exploding, but it works as long as you are gentle with it.
Will post the code in the playerfactory forum tonight.
It can serve as an example on how to make lousy springs. ;)

I basically check the distance between two rigidbodies.
If they are too far from each other I apply forces to pull them together and if they are too close to each other I apply forces that pushes them apart.(Like a "verlet" system)

One of the bodies are connected tighlty to the carbody with a ballsocket and the other with a hinge.

Since I cannot apply forces to each corner of the car body at the same time I had to connect a rigidbody at each corner using a ballsocket joint. This joint requires alot of iterations to stay in place due to the large forces acting on it.

I don't have any dampers so the springs oscillates alot.
A Jointconstraint however could serve as a kind of dampingdevice but it won't come to a smooth stop as real damper do.


Mac M(Posted 2004) [#49]
Hi Sweenie. How about breakage? Will we could break things in blitz using your amazing wrapper? Thanks


Genexi2(Posted 2004) [#50]
The damping joint thing looks really slick

I know, when I saw the demo first thing that came to my mind is "door"......ooh, now that'd be nice in an FPS game...

edit: you will need to get these meshes if you do not have them. Look for the thread "giving back to the community" in the blitz3d section


Any chance someone can link me to this thread? I cant freakin find it. >.<

[edit] Nvm, found it here : http://www.blitzbasic.com/Community/posts.php?topic=29994


bradford6(Posted 2004) [#51]
what does the 'slide' joint do? this could act like a spring/damper. no?


Sweenie(Posted 2004) [#52]
It could indeed be very helpful when creating springs & dampers but it seems the slider joint isn't working in the current version of Tokamak(not the wrapper).


poopla(Posted 2004) [#53]
I get User lib not found. The lib and decls are in the userlibs dir...

[Edit] Got it.


poopla(Posted 2004) [#54]
Theres no documentation for the wrapper at all?


Bot Builder(Posted 2004) [#55]
I've done some.

http://www.blitzcoder.com/cgi-bin/articles/show_article.pl?f=bot__builder102082004102230.html is one- A basics tut.

Here are some quick command refs for every command. hopefully I can update or someone can assist in adding examples.

Put one of these in your blitz directory and extract for F1 help access! (BTW I ran the html docs through a optimizer so it's not direct code2doc output)

Download this: http://blitzstuff.250free.com/zips/TokamakHelp.7z (15.5 KB) If you are cool, and have 7z.

Download this: http://blitzstuff.250free.com/zips/TokamakHelp.exe (83.7 KB) If you don't have 7z but still want to save 20KB and get a cool extractor thingy.

Download this: http://blitzstuff.250free.com/zips/TokamakHelp.zip (101 KB) If you want a clunky big zip

Pretty cool. I would have had to do alot more work to get this setup without cod2doc, however I still had to punch out 1,000 lines .


SirGorto(Posted 2004) [#56]
I have a fully functional wrapper done as I type this out for Tokamak physics. I have tested it a bunch and everything seems to work. Right now my fellow programmers are testing it out to find the bugs. we will be offering it for free at our website very soon. Keep watching the forums for details.

we will also be offering many other things to do with blitz in the future. many will have to do with tokamak physics and some will not. I am also currently working on a weather controller for simplistic creation of rain, snow, and lightning. The weather system is about 90 percent of the way to the final testing stages and will be available very soon as well. The weather system will include dynamic lightning which is generated on the fly.

Any interests or questions feel free to email me at
sirgorto@...
PLEASE HAVE A SUBJECT OF "BLITZ" for fast reply

If any of you have sugestions for a useful tool or dll for the blitz community please contact me as well with your thoughts. I havea small group of hard working programmers that loves a challenge. I look forward to hearing from you in the future. Thanks...


Bot Builder(Posted 2004) [#57]
Hmm. Why didn't you say somthing as already swenie has put alot of work into making his wrapper? I guess you're new and already made it before? hmm. well, it would be nice if the syntax was maintained as people have already produced programs for sweenie's V.4 wrapper, and I for one have produced documentation that would need revision. I take it every feature of tokamak is wrapped? currently I think we lack particles, collisioninfo, userdata, breakage, and sensors.

If you think about it this isn't very much, as userdata is simply two commands, breakage will just require a bit more functions (most of the tough stuff is handled). Particles will require a bit more work, and collisioninfo will probably be difficult to work out in an easy way,although sweenie I believe has a start on this. Personally, I look forward to collisioninfo and sensors the most.

My point is, Unless you're wrapper has no problems and the angles between tokamak and blitz work, it might be better to keep up the development of sweenie's wrapper which many are already familiar with.


Skitchy(Posted 2004) [#58]
There's no reason not to have 2 options. SirGorto - if you need any more testers I'd be happy to take a look. Have you got a decent car physics model going yet?


Bot Builder(Posted 2004) [#59]
Oh yeah.. didn't know you were looking for testers. I would gladly thouroughly test it.


BlitzSupport(Posted 2004) [#60]
The more options the better!


Sweenie(Posted 2004) [#61]
The more the merrier! :)

It will be interesting to see how your wrapper
works.


SirGorto(Posted 2004) [#62]
I agree Sweenie is the man!!! :) Now breakage and collision info is a very hard issue at least in my book. We have yet to get either fully working, but everything else is fully functional. I know we don't need two otpions really, but Right when we saw Tokamak physics we were developing a group of game developement dlls and figured why not use tokamak physics.

we will try to make our other dlls that work with tokamak work with either one easily. Basically The options will be there for two alternative interfaces with tokamak. Our team here wanted to have it done on a time table of our choosing, so nothing is wrong with sweenies developement.

We are interested in getting as many game creation tools to all of you guys as we can to make better games without the hype and hoopla of massive publishers.

The thing with tokamak is that there is hardly any documentation anywhere on how to use it itself, let alone how to write a wrapper for it. Anyone who can understand it all enough to wrap it up in a functional way so that it is usable by teh public is a good man...

I will keep you informed, and Sweenie feel free to email me if you have ideas about collision info and breakage. We are all looking in awe of thta problem. Keep u pthe good work...

sirgorto@...


AbbaRue(Posted 2004) [#63]
Have you seen any other 3D engines, that could be interfaced with Blitz3D?
Always looking for a faster outdoor engine dll.


Skitchy(Posted 2004) [#64]
OGRE looks quite good, but it would take a lot of 'wrapping'.


bradford6(Posted 2004) [#65]
Blitz is a great renderer. The interfaces should be for scripting .

Python or Lua.

I prefer Python but that's just me.

Python is an excellent 'glue' language.


bradford6(Posted 2004) [#66]
Blitz is a great renderer. The interfaces should be for scripting .

Python or Lua.

I prefer Python but that's just me.

Python is an excellent 'glue' language.


ckob(Posted 2004) [#67]
i geta server faluire when trying to download the wrapper


Sweenie(Posted 2004) [#68]
Hmm, it should be working.
Anyway, I'll mail it to you.


Rob(Posted 2004) [#69]
large it sweenie
did you work out the new fangled collision tabley wotsits?


Sweenie(Posted 2004) [#70]
Well, been thinking alot about that lately.

Either I make it very simple for me and just dump the collisionresults into one flat array and let the user iterate through it to retrieve the collisionresult or a "collisionfree" hashtable solution (sswift, no comments please ;) ) there finding specific collisionresult would be way faster than the flat array.
However, a hashtable with buckets containing linked lists would require many memory dealloc and allocations and that could affect performance(and maybe introduce memoryleaks if not done correctly).

I think I will start with the static flat array and see what the results are.

Upon collision Tokamak will return a collisioninfo(using callback) for every colliding bodypair. This collisioninfo consist of pointers to the the two colliding bodies, collisionnormal, contactpoints, geometries involved and materialinfo.

Suggestions are welcome.


Rob(Posted 2004) [#71]
Well I reakon it could be simple.

collided = CheckPair(tokobj1,tokobj2)
If collided then...

Oh I see what you mean, what method? well I don't think that it would require many memory allocations because simply, you play it safe and just set it to the maximum possible like blitz does with it's own types.

Blitz simply grows them as large as you like and does not dealloc, (only re-uses existing alloc) until program ends. Ie when you call the kill tokamak stuff.

Since this is beta you can feel free to add and remove commands that are subject to change. Don't feel you can't play with our source code like this because we welcome it - after all, the end result will be a system that works well... good luck.


ChrML(Posted 2004) [#72]
Userlib not found...

Both Tokomak.decls, and TokomakWrapper.dll are in the userdecls dir. Why? I get it at the first tokomak command.


Rob(Posted 2004) [#73]
you need the tokamak.dll obtainable for www.tokamakphysics.com

download the sdk and copy the dll to the program folder.


ChrML(Posted 2004) [#74]
Okay, thanks!


Litobyte(Posted 2004) [#75]
I always have been on ODE, but for many reason I wish to switch on tokamak for my tests.

Everything is setup and seems to work but...

What am I doing wrong ?
I'm trying to have a "wipeout"-like tokamak"ed" ship going on a tokamak cube, starting from (grabbin code from) the car demo "framework",
the problem is that the ship keeps going through the cube!

Where's the gap ?


Rob(Posted 2004) [#76]
go to www.playerfactory.co.uk and click the forum link for the "official" tokamak forum - usually get help a lot quicker.


poopla(Posted 2004) [#77]
How would I go about getting my rigid bodies to collide with a loaded mesh?


Bot Builder(Posted 2004) [#78]
http://playerfactory.proboards25.com/index.cgi?board=tokamak2&action=display&num=1077666832


Sweenie(Posted 2004) [#79]
Version 0.5 of the wrapper is now available.
www.freewebs.com/sweenie

Collisioninfo and handling are in.
Particles as well.


Mathieu A(Posted 2004) [#80]
Thank you very much sweenie!!


Rob(Posted 2004) [#81]
thanks sweenie! whats next? seems like it's complete now at last apart from breakages :)


koekjesbaby(Posted 2004) [#82]
i think you are forgetting hingejointmotors.


Zenith(Posted 2004) [#83]
And thingamajigs! You can't forget thingamajigs!


Gabriel(Posted 2004) [#84]
CollisionInfo? Sweet.


Bot Builder(Posted 2004) [#85]
Yes, very nice sweenie!

Also sensors - although I'm not sure how they compare to blitz linepicks, I'm willing to bet their pretty fast, and give you some info like material, depth, normal, point, and what rigid/animated body. Probably most useful for AI.


Rob(Posted 2004) [#86]
Can't work out how I can check if RBA has actually collided (or is still colliding with) RBB


Sweenie(Posted 2004) [#87]
After a call to the advance function the bank will be filled with collisionpairs.

small example...

RBA=TOKRB_Create()
TOKRB_SetCollisionID RBA,1
...
RBB=TOKRB_Create()
TOKRB_SetCollisionID RBB,1
...
TOKSIM_SetCollisionResponse 1,1,3
...

TOKSIM_Advance(timestep#,1)
;Collisioncheck
CollisionCount=TOKSIM_GetCollisionCount()

If CollisionCount>0 Then
 For c=0 to CollisionCount-1

  BodyA=PeekInt(ColBank,(c*104) + 0)
  BodyB=PeekInt(ColBank,(c*104) + 4)

  If (BodyA=RBA AND BodyB=RBB) OR (BodyA=RBB AND BodyB=RBA)
   ;RBA and RBB are colliding with each other
  EndIf

 Next
EndIf



Filax(Posted 2004) [#88]
Hi :) i'm trying to use tokamak with type i have try an example who use

Dim obj(Rigid_Bodies)
Dim rb(Rigid_Bodies)

For i=1 To Rigid_Bodies
obj(i) = CreateCube()
ScaleEntity obj(i),1,1,1
rb(i)=TOKRB_Create()
TOKRB_AddBox rb(i),2.0,2.0,2.0
TOKRB_SetPosition rb(i),Rnd(-40,40),30,Rnd(-40,40)
TOKRB_SetLinearDamping rb(i),0.001
TOKRB_SetAngularDamping rb(i),0.02
TOKRB_SetMass rb(i),2.0
TOKRB_SetBoxInertiaTensor rb(i),4.0,2.0,2.0,2.0
TOKRB_SetVelocity rb(i),Rnd(-10,10),Rnd(-10,10),Rnd(-10,10)
TOKRB_SetTorque rb(i),Rnd(-10,10),Rnd(-10,10),Rnd(-10,10)
Next


but if i try to do the same thing with type like :

Type Bullet
Field Entity
Field Simulator
Field Px#,Py#,Pz#
End Type

For i=1 To Rigid_Bodies
B.Bullet=New Bullet
B\Entity=CreateCube()
ScaleEntity B\Entity,1,1,1
b\simulator=TOKRB_Create()

TOKRB_AddBox b\simulator,2.0,2.0,2.0
TOKRB_SetPosition b\simulator,Rnd(-40,40),30,Rnd(-40,40)
TOKRB_SetLinearDamping b\simulator,0.001
TOKRB_SetAngularDamping b\simulator,0.02
TOKRB_SetMass b\simulator,2.0
TOKRB_SetBoxInertiaTensor b\simulator,4.0,2.0,2.0,2.0
TOKRB_SetVelocity b\simulator,Rnd(-10,10),Rnd(-10,10),Rnd(-10,10)
TOKRB_SetTorque b\simulator,Rnd(-10,10),Rnd(-10,10),Rnd(-10,10)
Next

i have an error message at
TOKRB_AddBox b\simulator,2.0,2.0,2.0

???? tokamak can work with type ? or i must use array ? DIM ?











this is the full code :

Const Rigid_Bodies=100,Animated_Bodies=5,Rigid_Particles=0

Type Bullet
Field Entity
Field Simulator
Field Px#,Py#,Pz#
End Type

TOKSIM_SetRigidBodiesCount Rigid_Bodies
TOKSIM_SetAnimatedBodiesCount Animated_Bodies
TOKSIM_SetRigidParticleCount Rigid_Particles
TOKSIM_SetControllersCount 0
TOKSIM_SetGeometriesCount Rigid_bodies+Animated_Bodies ;Assuming each one only has one geometry. Not true with more complex rigid bodies and animated bodies.

TOKSIM_CreateSimulator(0,-10,0)

Graphics3D 800,600,0,2
Const FPS=60
Global cam = CreateCamera()
PositionEntity cam,0,10,-50

l=CreateLight()
centerpoint=CreatePivot()

ground = CreateCube()
EntityColor ground,150,100,10
ScaleEntity ground,50,5,50
PositionEntity ground,0,-5,0
abground = TOKAB_Create()
TOKAB_AddBox(abground,100.0,10.0,100.0)
TOKAB_SetPosition(abground,0.0,-5.0,0.0)

MakeTokCollider(ground)

;Terrain = LoadMesh("oval_racetrack.b3d")
;ScaleMesh Terrain,0.25,0.25,0.25
;PositionEntity Terrain,0,-5,0
;MakeTokCollider(terrain)

;Dim obj(Rigid_Bodies)
;Dim rb(Rigid_Bodies)


For i=1 To Rigid_Bodies
B.Bullet=New Bullet
B\Entity=CreateCube()
ScaleEntity B\Entity,1,1,1
b\simulator=TOKRB_Create()

TOKRB_AddBox b\simulator,2.0,2.0,2.0
TOKRB_SetPosition b\simulator,Rnd(-40,40),30,Rnd(-40,40)
TOKRB_SetLinearDamping b\simulator,0.001
TOKRB_SetAngularDamping b\simulator,0.02
TOKRB_SetMass b\simulator,2.0
TOKRB_SetBoxInertiaTensor b\simulator,4.0,2.0,2.0,2.0
TOKRB_SetVelocity b\simulator,Rnd(-10,10),Rnd(-10,10),Rnd(-10,10)
TOKRB_SetTorque b\simulator,Rnd(-10,10),Rnd(-10,10),Rnd(-10,10)
Next

period=1000/FPS
time=MilliSecs()-period

imptime=MilliSecs()

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

For B.BUllet=Each bullet
PositionEntity B\Entity,TOKRB_GetX#(b\simulator),TOKRB_GetY#(b\simulator),TOKRB_GetZ#(b\simulator)
RotateEntity B\Entity,TOKRB_GetPitch#(b\simulator),TOKRB_GetYaw#(b\simulator),TOKRB_GetRoll#(b\simulator),False

If MouseHit(1) Then
B.Bullet=New Bullet
B\Entity=CreateCube()
ScaleEntity B\Entity,1,1,1

B\Simulator=TOKRB_Create()

TOKRB_AddBox B\Simulator,2.0,2.0,2.0
TOKRB_SetPosition B\Simulator,Rnd(-40,40),30,Rnd(-40,40)
TOKRB_SetLinearDamping B\Simulator,0.001
TOKRB_SetAngularDamping B\Simulator,0.02
TOKRB_SetMass B\Simulator,2.0
TOKRB_SetBoxInertiaTensor B\Simulator,4.0,2.0,2.0,2.0
TOKRB_SetVelocity B\Simulator,Rnd(-10,10),Rnd(-10,10),Rnd(-10,10)
TOKRB_SetTorque B\Simulator,Rnd(-10,10),Rnd(-10,10),Rnd(-10,10)
TOKRB_ApplyImpulse B\Simulator,0,0,10
EndIf

Next

EndIf
TOKSIM_Advance(1.5/FPS,1)
UpdateWorld
Next

camx#=Cos(rot#)*50
camz#=Sin(rot#)*50

rot#=rot#+0.05+MouseXSpeed()/5.0

If rot#>360 Then rot#=0
PositionEntity cam,camx#,40,camz#
PointEntity cam,centerpoint

RenderWorld tween
Flip False
Wend

TOKSIM_DestroySimulator()
End

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


ckob(Posted 2004) [#89]
this might be a dumb question but could this be used for like arrows? or crossbow bolts?


Sweenie(Posted 2004) [#90]
In theory, yes.
In real life, maybe.

Arrows, bolts & bullets are just the kind of objects Tokamak has most problems with because their small size and high velocity.
The chance of missed collisions is high.

But if you make sure they won't move too fast and make the simulator do many iterations(physicssteps) it might work.

I think arrows could work, but bolts & bullets should better be collisionchecked with linepick or the soon to be implemented TokamakSensor.

However thinking about it, you could let Tokamak handle the physicspart of the projectiles while you take care of the collisionpart.
By doing a lineintersectiontest between the projectile's current and last position for example.


IPete2(Posted 2004) [#91]
Sweenie,

couldn't ckob use an invisible larger elongated cube around the bolt to help with collision detection?

IPete2.


Sweenie(Posted 2004) [#92]
That could work but it depends on how accurate collision you want.
Consider an enemy hiding behind a tree and it's foot is sticking out. Chances are that you never can hit the foot but instead keep hitting the tree.
Now, this was a silly example but you get the idea.
That method wouldn't allow precision shooting, depending on the size of the surrounding cube of course.

But as always, the only way to really find out is to try it.

Anyway, I got an idea for the arrow.
Consider two rigidbodies(spheres) placed at both ends of the arrow, like this *-----*
Now the body located at the tip of the arrow should have a slighter larger mass then the one at the back.
The body at the back should have a slightly higher lineardamping then the one at the tip.
Connect them with a balljoint.
This should make it move somewhat like a real arrow.
hmmm, just a thought. :)


IPete2(Posted 2004) [#93]
That sounds really good.

btw has anyone produced a more indepth tutorial Tokamak demo yet? I am still discovering bits and pieces, but I want the 'full meal'!

I would really like to understand all this and the way it integrates with B3d a lot more thoroughly.

IPete2.


poopla(Posted 2004) [#94]
Anyone mind telling me why my rigid bodies will decide to suddenly hault all movement? :) Thanks.

[edit] And also where I can find what ConnectionType% values are for TOKJOINT_Create().


poopla(Posted 2004) [#95]
I don't seem to be able to create a joint that will simply make two rigid bodies act like one... like parenting? Any help?


Bot Builder(Posted 2004) [#96]
Most of this discussion should be moved to http://playerfactory.proboards25.com/ , but ohwell.

Ipete - Have you seen my tut on blitzcoder? some more are in the works.

Shattered - What you do is add multiple geometries to a single rigid body - using TOKRB_AddBox multiple times. These return a handle, allowing you to move them about with TOKGEOM_PositionAndRotate .


IPete2(Posted 2004) [#97]
bot builder,

Thanks - yes that was good to start with, but I really want to get inside Tokamak, so I can be inspired as to how else we can use it. I want total control over it all, mwahahahaha!

:)

I'm looking forward to your new tutorials.

IPete2.


DareDevil(Posted 2004) [#98]
what's use this library in blitz3D?
blitz send a message "lib.... not found"
this lib is not loaded for the command .lib "" ?

pleace help me!!

excuse for the my english


IPete2(Posted 2004) [#99]
DareDevil,

Make sure you have followed the download instructions and placed everything where it needs to be.

Check this link out.

www.blitzcoder.com/cgi-bin/articles/show_article.pl?f=bot__builder102082004102230.html .

IPete2.


cermit(Posted 2004) [#100]
I wonder who will get the 100 post... Doh!


Mr. Bill(Posted 2004) [#101]
Am in the process of writing a ship simulation application and am wondering if the Tokamak physics library able to simulate the physics of waterborne objects (ships, boats etc)?
Thanks in advance.


Sweenie(Posted 2004) [#102]
I haven't tried this yet but You should be able to get a somewhat realistic "ship on water simulation" by doing like this:

Create the simulator with normal gravity.

Create an animated body with a boxgeometry that will fit the watervolume.

Set collisionresponse between this body and other bodies to 4(No impulse will be generated, just collisioninfo)
This will make the simulator report if a body(boat/ship) is penetrating the animated body but will not make it bounce off it.

Now as soon as Tokamak reports a collision with the watervolume you will have to detect somehow how much volume of the ship are in the water and generate an upward force that will push the boat to the surface.
This should make the boat float on the surface.


Danny(Posted 2004) [#103]
Hi Sweenie,

Thanks again for the excellent wrapper!

Would it be possible in the next release to implement/support the GetUserData() / SetUserData() functions?

This way I can store object ID's in the RB's and access my objects (types) directly (using object() and handle() in blitz) in stead of finding a match between my entity and a RB in a huge for..next loop?!

thanks-
Danny


Sweenie(Posted 2004) [#104]
Yep, I will make sure Userdata is implemented in the next release along with Sensors and Hingemotor.


Danny(Posted 2004) [#105]
That be sweet! Thanks man!

D.


Bot Builder(Posted 2004) [#106]
ohh. Sensors. Yay!

I have a new article up on blitzcoder. http://www.blitzcoder.com/cgi-bin/articles/show_article.pl?f=bot__builder103252004031037.html

It's on static Meshs and is a sequel to the previous one.


bradford6(Posted 2004) [#107]
sensors are cool. this would be great to implement vehicle spring fizics--yes?


skidracer(Posted 2004) [#108]
thread continued here:

http://www.blitzbasic.com/Community/posts.php?topic=32503