tokamak physics thread 2:

Blitz3D Forums/Blitz3D Programming/tokamak physics thread 2:

(tu) sinu(Posted 2004) [#1]
New thread, old one is to big, please post in here now if you don't mind, helps the modem users.


RayTracer(Posted 2004) [#2]
Tokamak is awesome , but collisions with terrains could be a problem ,since you can't GetSurface from a terrain...


GfK(Posted 2004) [#3]
I had a problem with the terrain demo. A few of the objects dropped straight through. :/


DarkEagle(Posted 2004) [#4]
probably best with a mesh terrain rather than a blitz terrain? the moving verts cant really be helping...


Jeremy Alessi(Posted 2004) [#5]
Hmmm... I don't have a Tokamakdll.dll I only have a Tokamakdll.dsp. Yes everything is in the current directory and I still have the same folder setup it had when I unzipped it too.


jhocking(Posted 2004) [#6]
Don't forget the actual dll is a separate download you have to get from the Tokamak website. Sweenie's download is just the wrapper.


skidracer(Posted 2004) [#7]
Go Sweenie!

In case ppl missed out on initial thread visit this site for some physices tokamak style - www.freewebs.com/sweenie

ban, if you are messing with c++ projects maybe start a new thread to avoid confusion?


DarkEagle(Posted 2004) [#8]
can anybody explain the process of making a b3d exported from maplet work with this? i have an idea using 2 copies of the mesh, one of them having just one surface...


Ice9(Posted 2004) [#9]
Very nice Sweenie MUU!!


DarkEagle(Posted 2004) [#10]
never mind, sorted it :) requires 2 copies of the mesh though, one of them needs to have just one surface and is hidden. Is this naming convention for the tok functions going to stay? if so il create some nice functions :)


Bot Builder(Posted 2004) [#11]
why does it have to be single surface? Can't you just tell it where all your tris are?


Vorderman(Posted 2004) [#12]
So what's the deal with distributing the TokamakDLL file with your programs? If the system is free for commercial use, how can you not be able to distribute the DLL?


Koriolis(Posted 2004) [#13]
You can.
It's when you're making a physics engine or the like (say...a wrapper for tokamak) that you can't distribute yourself the tokamak DLL.
For you game no prob.

At least that's waht I understood.


AL(Posted 2004) [#14]
GFK, i had the same problem of some objects falling through the landscape.

Ive just been through the terrain tutorial briefly (find it here!) and you have to set the maximum number of collisions that can happen at any one time, i guess its exceeding this value when you see the objects going through the terrain.


Bot Builder(Posted 2004) [#15]
I checked; you can just loop through your surfaces grabbing all the tris and putting them in you bank. Why would you need another entity?

Very, very nice sweenie!

how bout making the function called 'TOKSIM_SetStaticMesh' instead of 'TOKSIM_SetTerrainMesh' people might get confused and think it has to be a terrain.


DarkEagle(Posted 2004) [#16]
you can? can somebody code a function for me that does this with every mesh i pass to to it? at the moment i have this for my collision entity...

Function MakeTokCollider(mesh)

	surface = GetSurface(mesh,1)
	
	;fill bank with vertices
	vertices=CreateBank(16*CountVertices(surface))
	offset=0
	For v=0 To CountVertices(surface)-1
	 PokeFloat vertices,offset,VertexX#(surface,v)
	 PokeFloat vertices,offset+4,VertexY#(surface,v)
	 PokeFloat vertices,offset+8,VertexZ#(surface,v)
	 PokeFloat vertices,offset+12,0.0
	 offset=offset+16  
	Next
	
	;fill bank with triangles
	triangles=CreateBank(24*CountTriangles(surface))
	offset=0
	For v=0 To CountTriangles(surface)-1
	 PokeInt triangles,offset,TriangleVertex(surface,v,0)
	 PokeInt triangles,offset+4,TriangleVertex(surface,v,1)
	 PokeInt triangles,offset+8,TriangleVertex(surface,v,2)
	 PokeInt triangles,offset+12,0
	 PokeInt triangles,offset+16,0
	 PokeInt triangles,offset+20,0
	 offset=offset+24  
	Next
	
	;Hand over the terrain data to Tokamak
	TOKSIM_SetTerrainMesh vertices,CountVertices(surface),triangles,CountTriangles(surface) 
	
	; Now we can free the banks as Tokamak has copied all data
	FreeBank vertices
	FreeBank triangles

End Function


i also made these:

Function CreateTokCube(entity,rb,x#,y#,z#,xs#=1.0,ys#=1.0,zs#=1.0,mass#=1.0)

	ScaleEntity entity,xs,ys,zs
	PositionEntity entity,x,y,z
	
	TOKRB_AddBox rb,xs*2,ys*2,zs*2
	TOKRB_SetPosition rb,x,y,z
	TOKRB_SetLinearDamping rb,0.001
	TOKRB_SetMass rb,mass
	TOKRB_SetBoxInertiaTensor rb,xs,ys,zs,mass

End Function


Function CreateTokSphere(entity,rb,x#,y#,z#,rad#=1.0,mass#=1.0)

	ScaleEntity entity,rad,rad,rad
	PositionEntity entity,x,y,z
	
	TOKRB_AddSphere rb,rad#*2
	TOKRB_SetPosition rb,x,y,z
	TOKRB_SetLinearDamping rb,0.001
	TOKRB_SetMass rb,mass
	TOKRB_SetBoxInertiaTensor rb,rad,rad,rad,mass

End Function


Function CreateTokCylinder(entity,rb,x#,y#,z#,rad#=1.0,height#=1.0,mass#=1.0)

	TOKRB_AddCylinder rb,rad*2,height
	TOKRB_SetPosition rb,x,y,z
	TOKRB_SetLinearDamping rb,0.001 
	TOKRB_SetAngularDamping rb,0.01 
	TOKRB_SetMass rb,mass
	TOKRB_SetCylinderInertiaTensor rb,rad*2,height,mass

End Function


to be used as such:

	nr=Rnd(1,3)	
		
	If nr=1 Then
		obj(i) = CreateCube()
		rb(i) = TOKRB_Create()
		CreateTokCube(obj(i),rb(i),x#,15+i*0.2,z#,1,1,1,2)
	ElseIf nr=2 
		obj(i) = CreateSphere()
		rb(i) = TOKRB_Create()
		CreateTokSphere(obj(i),rb(i),x#,15+i*0.2,z#,1,1.5)
	ElseIf nr=3 
		obj(i) = CreateCylinder()
		rb(i) = TOKRB_Create()
		CreateTokCylinder(obj(i),rb(i),x#,15+i*0.2,z#,1,1,2)
	EndIf


figured it might help you guys...


Binary_Moon(Posted 2004) [#17]
how bout making the function called 'TOKSIM_SetStaticMesh' instead of 'TOKSIM_SetTerrainMesh' people might get confused and think it has to be a terrain.


You could just edit the decls file yourself. Of course getting it changed in the global distribution would be better but...

Sweenie - This is all very cool. I will have to have a play with this properly some time; I've wanted decent physics for ages.


Bot Builder(Posted 2004) [#18]
I'll post it in a minute... It's a bit harder than I thought, as the triangls's vertice indices will be screwed up.

BTW, I get no 'through the terrain' problems unless I jack it up to 500 entities. at 200 its fine. Tokomak time is wrong though. it says its taking 300 ms. while with a total-process timer its only 20?


Skitchy(Posted 2004) [#19]
Is the constraint thing in yet? I'm assuming it would be necessary to do a car physics sim? Anybody know? :-/


Bot Builder(Posted 2004) [#20]
try this out real quick. I doubt it'll work. I probably made an error somewhere as it is quite a complex thing :( however very useful to have.

[edit]took out the code cause there's a better one down below

this hopefully handles multi-surface entities.


DarkEagle(Posted 2004) [#21]
doesnt seem to :( the tris seem to be getting messed up somewhere.

it needs to be:

TOKSIM_SetTerrainMesh vertices,ttlvert,triangles,ttltris

rather than:

TOKSIM_SetTerrainMesh vertices,CountVertices(surface),triangles,CountTriangles(surface)

though...

/edit/ still nothing /edit/


Bot Builder(Posted 2004) [#22]
As you can see I already changed that :) musta posted while I updated :)


DarkEagle(Posted 2004) [#23]
yeah, still doesnt work :P looks like multi-surface is a tad tougher? possibly rebuilding mesh into one surface, then passing this through is a better idea? the new mesh could be deleted afterwards...


Bot Builder(Posted 2004) [#24]
not sure if that works, but try it again. I changed it a bit more.


DarkEagle(Posted 2004) [#25]
youl never guess what... still doesnt work :P i have to go to bed now, if your going to carry on then good luck ;)


Tom(Posted 2004) [#26]
You gotta check this out, I was testing the Joint types (I know we aint got proper axle type joints 'yet') but anyways, I created a galloping box LOL!

Just hold space down

[code]
; Joint tests, trying to simulate vehicle axles
;
; I got a galloping car instead hehe
;
; Scouse

Const FPS=50


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

WireFrame False

Const ENTS=5

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

TOKSIM_CreateSimulator(ENTS,5,0,-10,0)

ground = CreateCube()
EntityColor ground,5,5,55
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)

wall1 = CreateCube()
EntityColor wall1,25,25,55
ScaleEntity wall1,2,10,50
PositionEntity wall1,50,0,0
abwall1 = TOKAB_Create()
TOKAB_AddBox(abwall1,4.0,20.0,100.0)
TOKAB_SetPosition(abwall1,50.0,0,0.0)

wall2 = CreateCube()
EntityColor wall2,25,25,55
ScaleEntity wall2,2,10,50
PositionEntity wall2,-50,0,0
abwall2 = TOKAB_Create()
TOKAB_AddBox(abwall2,4.0,20.0,100.0)
TOKAB_SetPosition(abwall2,-50.0,0,0.0)

wall3 = CreateCube()
EntityColor wall3,25,25,55
ScaleEntity wall3,50,10,2
PositionEntity wall3,0,0,-50
abwall3 = TOKAB_Create()
TOKAB_AddBox(abwall3,100.0,20.0,4.0)
TOKAB_SetPosition(abwall3,0.0,0,-50.0)

wall4 = CreateCube()
EntityColor wall4,25,25,55
ScaleEntity wall4,50,10,2
PositionEntity wall4,0,0,50
abwall4 = TOKAB_Create()
TOKAB_AddBox(abwall4,100.0,20.0,4.0)
TOKAB_SetPosition(abwall4,0.0,0,50.0)


Dim obj(ENTS)
Dim rb(ENTS)

obj(1) = CreateCube()
ScaleEntity obj(1),.5,.5,1
rb(1) = TOKRB_Create()
TOKRB_AddBox rb(1),1.0,1.0,2.0
;TOKRB_CollideConnected rb(1),True
TOKRB_SetPosition rb(1),0,2,0
PositionEntity obj(1),0,2,0
TOKRB_SetLinearDamping rb(1),0.001
TOKRB_SetAngularDamping rb(1),0.001
TOKRB_SetMass rb(1),2.0
TOKRB_SetBoxInertiaTensor rb(i),1,1,2,2.0

obj(2) = CreateSphere()
ScaleEntity obj(2),.5,.5,.5
rb(2) = TOKRB_Create()
;TOKRB_CollideConnected rb(2),True
TOKRB_AddSphere rb(2),1
TOKRB_SetPosition rb(2),-1,1.5,0.7
PositionEntity obj(2),-1,1.5,0.7
TOKRB_SetAngularDamping rb(2),0.02
TOKRB_SetLinearDamping rb(2),0.001
TOKRB_SetMass rb(2),0.5
TOKRB_SetSphereInertiaTensor rb(2),1,1

obj(3) = CreateSphere()
ScaleEntity obj(3),.5,.5,.5
rb(3) = TOKRB_Create()
;TOKRB_CollideConnected rb(3),True
TOKRB_AddSphere rb(3),1
TOKRB_SetPosition rb(3),1,1.5,0.7
PositionEntity obj(3),1,1.5,0.7
TOKRB_SetAngularDamping rb(3),0.02
TOKRB_SetLinearDamping rb(3),0.001
TOKRB_SetMass rb(3),0.5
TOKRB_SetSphereInertiaTensor rb(3),1,1

obj(4) = CreateSphere()
ScaleEntity obj(4),.5,.5,.5
rb(4) = TOKRB_Create()
;TOKRB_CollideConnected rb(5),True
TOKRB_AddSphere rb(4),1
TOKRB_SetPosition rb(4),-1,1.5,-.7
PositionEntity obj(4),-1,1.5,-.7
TOKRB_SetAngularDamping rb(4),0.02
TOKRB_SetLinearDamping rb(4),0.001
TOKRB_SetMass rb(4),0.5
TOKRB_SetSphereInertiaTensor rb(4),1,1


obj(5) = CreateSphere()
ScaleEntity obj(5),.5,.5,.5
rb(5) = TOKRB_Create()
;TOKRB_CollideConnected rb(5),True
TOKRB_AddSphere rb(5),1
TOKRB_SetPosition rb(5),1,1.5,-.7
PositionEntity obj(5),1,1.5,-.7
TOKRB_SetAngularDamping rb(5),0.02
TOKRB_SetLinearDamping rb(5),0.001
TOKRB_SetMass rb(5),0.5
TOKRB_SetSphereInertiaTensor rb(5),1,1

;obj(i) = CreateCylinder()
;rb(i) = TOKRB_Create()
;TOKRB_AddCylinder rb(i),2.0,1.0
;TOKRB_SetPosition(rb(i),x#,2+i*0.2,z#)
;TOKRB_SetAngularDamping rb(i),0.02
;TOKRB_SetLinearDamping rb(i),0.001
;TOKRB_SetMass rb(i),2.0
;TOKRB_SetCylinderInertiaTensor rb(i),2.0,1.0,2.0


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


axletype=1

axle1=TOKJOINT_Create (2,rb(1),rb(2))
TOKJOINT_SetPositionWorld axle1,-.5,1.5,.7
TOKJOINT_SetType axle1,axletype
TOKJOINT_Enable axle1,True

axle2=TOKJOINT_Create (2,rb(1),rb(3))
TOKJOINT_SetPositionWorld axle2,.5,1.5,.7
TOKJOINT_SetType axle2,axletype
TOKJOINT_Enable axle2,True

axle3=TOKJOINT_Create (2,rb(1),rb(4))
TOKJOINT_SetPositionWorld axle3,-.5,1.5,-.7
TOKJOINT_SetType axle3,axletype
TOKJOINT_Enable axle3,True

axle4=TOKJOINT_Create (2,rb(1),rb(5))
TOKJOINT_SetPositionWorld axle4,.5,1.5,-.7
TOKJOINT_SetType axle4,axletype
TOKJOINT_Enable axle4,True



Centerpivot = CreatePivot()

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

rot#=0

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

imptime=MilliSecs()
; 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.0/FPS)

If rot#>360 Then rot#=0

;PositionEntity camera,camx#,40,camz#
PointEntity camera,centerpivot
UpdateWorld

Next

; Not sure wether to put this here or inside the for/next above...
For i=1 To 5
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

If KeyDown(57) Then
; i=Rnd(1,ENTS)
; TOKRB_ApplyImpulse rb(i),Rnd(-3.0,3.0),Rnd(15,30),Rnd(-3.0,3.0)
; TOKRB_ApplyImpulse2 rb(i),0,30,0,TOKRB_GetX#(rb(i))+0.5,TOKRB_GetY#(rb(i))-0.5,TOKRB_GetZ#(rb(i))+0.5
TOKRB_ApplyTwist rb(2),1,0,0
TOKRB_ApplyTwist rb(3),1,0,0
TOKRB_ApplyTwist rb(4),1,0,0
TOKRB_ApplyTwist rb(5),1,0,0

; TOKRB_SetForce rb(i),0,0,-10
; TOKRB_SetForce2 rb(i),0,0,-10,TOKRB_GetX#(rb(i))+0.5,TOKRB_GetY#(rb(i))-1.5,TOKRB_GetZ#(rb(i))+0.5
; For i=1 To ENTS
;TOKRB_SetTorque rb(i),0,60,0
; Next
EndIf

RenderWorld tween

Text 0,0,"Physics Time:"+TOKSIM_GetPhysicsTime()*1000.0+ " milliseconds"
Text 0,10,"Render Time:"+Str(elapsed)+ " milliseconds"
Flip False

Wend

TOKSIM_DestroySimulator()

End
[/CODE]

Have fun!
Tom


Bot Builder(Posted 2004) [#27]
lol. that's awesome :)

Darkeagle, Can you send me the code and model your using so I can work on it? You method would work, but I'd rather try a method that's pure data manipulation before doing that.

bot_builder56 AT fastmail.fm

(replace the AT with @)

updated the code. if it doesn't work, please mail me.


puki(Posted 2004) [#28]
That galloping box is cute - f'nar - could be turned into a virtual puppy.


Craig H. Nisbet(Posted 2004) [#29]
Hey guys, I just jumped in on this thread. I don't have much experience with whole userlib thing. I downloaded the dll and related files, and copied to my user lib dir. Looks like the command came in fine but it claims that it can't find the userlib, I'm assuming it means the dll. Is that supposed to be in a specific place?


Jeremy Alessi(Posted 2004) [#30]
I think you need the .dll from tokamakphysics.com, I had the same problem but haven't tested it out yet as I switched machines.


xmlspy(Posted 2004) [#31]
the demos are awesome, this seems to be the best physics engine for Blitz3D, keep up the good work.


darklordz(Posted 2004) [#32]
How to install sweenie's wrapper:

First unpack the userlibs\Tokamak.decls file into your blitz3d\userlibs folder. Also unpack userlibs\TokamakWrapper.dll into your blitz3d\userlibs folder.

Then download tokamak_lib_1010.zip and unpack lib\tokamakdll.dll to either your system32 folder of the folder that your tokamak samples are launched from. Otherwise you'll get the userlib not found error.....

To recap. You need 2 dll's the wrapper and the actual physics lib.

Nice work Sweenie :Restecpa!


MattG(Posted 2004) [#33]
is there a command i can use to tell if somthing has collided ? ie when a ball hits the ground ? or do i have to do that within blitz using blitz colision ?

thanks

Matt


Sweenie(Posted 2004) [#34]
Rigid and Animated bodies can be freed, check the Tokamak.decls file for reference.

how bout making the function called 'TOKSIM_SetStaticMesh' instead of 'TOKSIM_SetTerrainMesh' people might get confused and think it has to be a terrain.


I've tried to stay with the names in the actual physicsdll, but I have to agree, setterrainmesh is misleading.
I will change this in the next release.

The same goes for animatedbodies. I don't really think they are supposed to be moved once the simulation has started.
If you move an animbody towards a rigidbody it will go right through if the velocity is to high.
StaticBodies would have been a better name for them.
Unless they can be moved and I simply do something wrong in my simulations.

Is the constraint thing in yet? I'm assuming it would be necessary to do a car physics sim? Anybody know? :-/

I'm currently working on the jointlimits. Should be implemented in the next release.

is there a command i can use to tell if somthing has collided ? ie when a ball hits the ground ? or do i have to do that within blitz using blitz colision ?


Since Tokamak uses Callbacks for collisioninfo I have to come up with some way to feed the collisioninfo to Blitz.
I will probably fill some kind of collisiontable and then the user can retrieve collisioninfo for a certain body or bodies.
hmm, like how you retrieve collisioninfo in blitz today I suppose.


RayTracer(Posted 2004) [#35]
it would be useful if we had something like this:
...
tok_mesh=createmesh()
mesh1=loadmesh("mesh1.3ds")
AddToMesh(mesh1)
mesh2=loadmesh("mesh2.3ds")
AddToMesh(mesh2)
...
TOKSIM_SetTerrainMesh...

AddToMesh is a function that adds vertices to a mesh(tok_mesh in this case) from another certain mesh ,and then give it to tokamak as the static mesh.
Just a thought


Mark Judd(Posted 2004) [#36]
Sweenie,

Appreciate you've plenty to be going on with, but any chance of adding a :-

TOKSIM_SetMaterial(s32 index,friction,restitution)

since my car model works ace apart from driving everywhere on ice!!

Thanks in advance.

/EDIT Sorry Sweenie, just read your worklog a little better - realise you had this planned already.


DarkEagle(Posted 2004) [#37]
parp :) i have some issues with objects falling through a mesh if they are travelling too fast... any fixes?


LostCargo(Posted 2004) [#38]
that seems to happen also with blitz's collision systems too if im correct.


RayTracer(Posted 2004) [#39]
to increase accuracy you should do this
const iterations=5
...
 for i=1 to iterations
          TOKSIM_Advance(1.5/(FPS*iterations))
 next

its slower but more accurate ,increase the number of iterations if necessary


bradford6(Posted 2004) [#40]
alot of these question could be addressed if you guys would go to www.tokamakphysics.com and look at the documentation.

Sweenie did not write Tokamak, he is creating the bridge between Tokamak <===> Blitz-3d.

...and he is doing a damn fine job I might add :)


CopperCircle(Posted 2004) [#41]
"If you move an animbody towards a rigidbody it will go right through if the velocity is to high."

Is there anyway to create a mesh that has dynamic collisions with the rigid bodies at speed?


bradford6(Posted 2004) [#42]
you could connect rigid bodies together and the resulting
RB > RB would produce a collision.


Paul "Taiphoz"(Posted 2004) [#43]
Question is your zip all you need. ? Or do I need to download the SDK from the other website ?

Only asking cos I had a quick look today and none of the demos worked. but I didnt download the SDK.


IPete2(Posted 2004) [#44]
Yavin,

Look further up this thread.

It is explicitly explained for us (I had the same problems initially!)

Cheers,

IPete2.


Bot Builder(Posted 2004) [#45]
okay Darkeagle :) got it working. multisurface meshs :) I'll take ghostdag's suggestion and try making it multi-mesh as well as multi-surface.
[edit]see below for a new version
turns out I had a '-1' where it shouldn't have been.


bradford6(Posted 2004) [#46]
DOWNLOAD my new tokamak demo from this thread...


RayTracer(Posted 2004) [#47]
Good work bot builder


fredborg(Posted 2004) [#48]
You can use this to create the tokamak terrain mesh, from a segmented model:
Function TOK_MakeCollider(entity,trisbank=0,vertbank=0,rec=False)

	If EntityClass(entity) = "Mesh"
	
		If rec = False
			vertbank = CreateBank(0)
			trisbank = CreateBank(0)
			
			f_vert = 0
			f_tris = 0
		Else
			f_vert = BankSize(vertbank)/16
			f_tris = BankSize(trisbank)/24
		End If
				
		n_surf = CountSurfaces(entity)
		For s = 1 To n_surf
			surf = GetSurface(entity,s)
			
			n_vert = CountVertices(surf)
			n_tris = CountTriangles(surf)
	
			ResizeBank vertbank,(n_vert+f_vert)*16			
			ResizeBank trisbank,(n_tris+f_tris)*24
			
			For v = 0 To n_vert-1
				bankoffset = (f_vert+v)*16
			
				TFormPoint VertexX#(surf,v),VertexY#(surf,v),VertexZ#(surf,v),entity,0
			
				PokeFloat vertbank,bankoffset	,TFormedX()
				PokeFloat vertbank,bankoffset+4	,TFormedY()
				PokeFloat vertbank,bankoffset+8	,TFormedZ()
				PokeFloat vertbank,bankoffset+12,0.0
			Next
			
			For t = 0 To n_tris-1
				bankoffset = (f_tris+t)*24
			
				PokeInt trisbank,bankoffset   ,f_vert+TriangleVertex(surf,t,0)
				PokeInt trisbank,bankoffset+4 ,f_vert+TriangleVertex(surf,t,1)
				PokeInt trisbank,bankoffset+8 ,f_vert+TriangleVertex(surf,t,2)
				PokeInt trisbank,bankoffset+12,0
				PokeInt trisbank,bankoffset+16,0
				PokeInt trisbank,bankoffset+20,0
			Next	
			
			f_vert = f_vert + n_vert
			f_tris = f_tris + n_tris
		Next
		
	End If

	n_child = CountChildren(entity)
	For c = 1 To n_child
		TOK_MakeCollider(GetChild(entity,c),trisbank,vertbank,True)
	Next
			
	If rec = False
		If vertbank<>0 And trisbank<>0
			f_vert = BankSize(vertbank)/16 
			f_tris = BankSize(trisbank)/24
		
			TOKSIM_SetTerrainMesh vertbank,f_vert,trisbank,f_tris

			FreeBank vertbank
			FreeBank trisbank
		End If
	End If
	
End Function

Just use it like this:
bob = LoadAnimMesh("MyAwesomeLevel.b3d")
TOK_MakeCollider(bob)

And you're done. :)

This tokamak stuff rocks!


Sweenie(Posted 2004) [#49]
I just want to mention something about the GetPhysicsTime function.
You can retrieve different timereports in Tokamak and currently I have set it to RUNNING_AVERAGE.
This means that the timevalue you get is not the computiontime for the last frame but instead an average.

I will let the user choose different timereports in future releases.
You will also be able to choose what part of the physics to be measured. Currently it sums all calculations together but you can choose to only get the compution time for jointsolving, bodies, collisions and so on.


Skitchy(Posted 2004) [#50]
How do you connect 2 tokamak objects together in a rigid way? ie. putting legs on a table - one box for the top and 4 for the legs? Sort of like parent/child in Blitz. I've tried usin 3 joints to kind of 'glue' them together, but it doesn't seem to work.

EDIT : I think I just saw the answer in my head :)

@Sweenie - What do you think to changing the units so that they match standard Blitz objects? It seems at the moment that 1 Blitz unit=2 Tokamak units. Get's a bit annoying after a while. Could you change the wrapper to compensate? Or am I missing something (again) ;)


Koriolis(Posted 2004) [#51]
You'd probably need to set up constraints, but they are not yet available in the wrapper. Sweenie's working on it.


Bot Builder(Posted 2004) [#52]

@Sweenie - What do you think to changing the units so that they match standard Blitz objects? It seems at the moment that 1 Blitz unit=2 Tokamak units. Get's a bit annoying after a while. Could you change the wrapper to compensate? Or am I missing something (again) ;)
How could one blitz unit equal 2 tokomak units? it doesn't matter. that's why there are gravity settings, alowing you to have a large gravity if each unit is a small amount and a small gravity if each unit is a large amount. It all depends on your world scale. bradford6's demo might 'look unrealistic to some' but thats simply because you're imagining it at a different scale. say the demo was inside a little 1 ft. by 1 ft. box. then gravity would be pretty large. if each sphere is the size of a house, then gravity would be alot smaller.

nice code fredborg :) I assume setting rec prevents it from actually creating a mesh, allowing you to fiddle with it. Why not make the banks and varsglobal? then, on the last entity (or with a seperate command) you could set rec to false and have it write the collision mesh with all the entities you've called with TOK_MakeCollider. Basically, call it multiple times to have multiple meshs added into the collision mesh.


Bot Builder(Posted 2004) [#53]
Here's a new version of my code that handles multiple meshes, multiple surfaces, and hierarchal meshs(if you set the recursive parameter to true). :)

Global vertices=CreateBank(0),triangles=CreateBank(0)
Global offsett,offsetv,tric,ttlvert,ttltris

Function TOK_AddMesh(mesh,recurse=0)
 scount=CountSurfaces(mesh)
 For ind=1 To scount
  surface=GetSurface(mesh,ind)
  ttltris=ttltris+CountTriangles(surface)
  ttlvert=ttlvert+CountVertices(surface)
 Next
 ResizeBank triangles,ttltris*24
 ResizeBank vertices,ttlvert*16
 For ind=1 To scount
  surface = GetSurface(mesh,ind)
  ctr=CountTriangles(surface)
  tric=tric+cvt 
  cvt=CountVertices(surface)
  ;add vertices to bank
  For v=0 To cvt-1 
   TFormPoint VertexX#(surface,v),VertexY#(surface,v),VertexZ#(surface,v),mesh,0
   PokeFloat vertices,offsetv,TFormedX()
   PokeFloat vertices,offsetv+4,TFormedY()
   PokeFloat vertices,offsetv+8,TFormedZ()
   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
 If recurse Then 
  children=CountChildren(mesh)
  If children>0 Then
   For childcount = 1 To children
    child = GetChild(mesh,childcount)
    TOK_AddMesh child  
   Next 
  EndIf
 EndIf
End Function

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


To use, for each mesh you want it to collide with, use the TOK_AddMesh. To make it use all the meshs in the mesh's hierarchy, set 'recursive' to true. Then, when your done adding meshs do 'TOK_SetMesh' to transfer it to tokomak and delete the banks. The globals need to be declared at the start of the proggie.


Skitchy(Posted 2004) [#54]
@bot builder
I should have been more specific :) If you create a Blitz cube that is 1 unit in size and attach it to a Tokamak cube that is 1 unit in size you will notice that the 2 don't match. You have to scale the Tokamak cube up by a factor of 2 - at least that's what I've been doing.
I agree that the gravity stuff is all relative, but the geometry primitives don't match.

Anyway, could somebody explain how you would attach 2 objects in a child/parent manner. By that I mean :
If you have a beach-ball mesh then you can just match it to a Tokamak sphere and it will work fine. BUT if you have a lollipop mesh you'd need a Tokamak cylinder+sphere. Now, the thing is that there isn't a way (ATM) to offset the sphere so that it sits toward one end of the cylinder.
I've tried using 3 joints in a triangular formation and essentially 'glueing' two objects together, but it hasn't worked for me so far.

I know this can be done because i've seen the Tokamak demos, but having scanned the docs I can't see how to achieve it.

Having said that, the AddGeometry() command might have something to do with it. Can you actually have 2 arbitrary meshes sent to Tokamak as rigid/animated bodies? Probably not, but would be nice ;)


bradford6(Posted 2004) [#55]
addgeometry() will have to be a tokamak function and sweenie has not implemented that into it yet.

this would have nothing to do with blitz.

the best way to think about tokamak is that it is an invisible collision entity and you simply position and rotate blitz meshes to visually mark it.


Sweenie(Posted 2004) [#56]
In the next release you can position and rotate the geometries within the rigidbody.(You can add several geoms to one single body in the v0.1 and v0.2 but you can't position or rotate them)
The reason that it isn't implemented yet is because I had some problems with my Euler2Matrix code. But I've got it working now.
However, the really tricky part when using several different primitives in one body is to calculate the inertiatensor. For the lollipop you could probably get away with a boxinertiatensor.
Maybe someone on this forum knows how to calculate the inertiatensor(a 3-dimensional vector) when it's not a box,sphere or cylinder.

About the Blitz/Tokamak units.
When you create a cube in blitz using CreateCube it's width,height and depth is actually 2.0 because the cube extends from -1.0 to 1.0(Check the blitzdocs)
A cube in Tokamak created with 1.0,1.0,1.0 as parameter extends from -0.5 to 0.5 in all axes.


Jeroen(Posted 2004) [#57]
Sweenie, your effords bringing Tokamak to Blitz is very much appriciated!!!

Does Tokamak support rag doll? (in fact, is rag doll just something like assigning parameters to a mesh joint, plus constraints?). Rag doll is not that important comparing to the stuff you already implemented though (it's a hyped feature I think) but it would be nice nevertheless.

And what about car-like physics? (there are some special physics for those purposes I believe).

Anyway, thumbs up.


Skitchy(Posted 2004) [#58]
Thanks Sweenie :) That's what I wanted ;)

Great work!


(tu) sinu(Posted 2004) [#59]
ragdoll isn't hyped, especially if you apply it right, it's just like any other graphical physics effect.

Anyone upto doing some ropes physics in tokamak,i'd try but my hands are full for a while.


aCiD2(Posted 2004) [#60]
im working on some rope physics, going to use rigid bodys on each vertex maybe? something like that, ill give it a try :)


Midnight(Posted 2004) [#61]
Are people using different tokamak.decls? I have no problem running the first few demos by sweenie, but some of the demos posted in the first thread use e.g. CreateSimulator() rather than TOKSIM_CreateSimulator(), and the former is not recognized by my setup.

Help?


Tom(Posted 2004) [#62]
Hi all,

I've moved my reply to the Player Factory forums. I think that these Tokamak threads are specific, popular, and might end up swamping BB forums, so a home of their own seems appropriate :)

Jeroen: My original reply can be viewed here, thanks!

http://playerfactory.proboards25.com/index.cgi?board=tokamak&action=display&num=1074960769

Cya!
Tom


AL(Posted 2004) [#63]
Hi Midnight,

Sweenie has currently released the second version of the wrapper, the changes involved adding the word 'TOK' to all of the commands. The demos posted in the first thread were written with the first version of the wrapper, hence missing the 'TOK' bit.


IPete2(Posted 2004) [#64]
Hey guys,

for a Bullet Time effect check out my separate post in this forum.

IPete2.


CyBeRGoth(Posted 2004) [#65]
I wonder if anyone can solve this?

Say you have a ball, and you can push it forward using
TOKRB_ApplyImpulse OBJECT,X,Y,Z

This allows you to push the ball, forward, back, left, right
but what if you wanted to rotate the ball with the left/right arrows and push it forward with the up arrow key? how could you do this with Tokamak, i tried the rotation commands but still cant get it.
Can someone with some experience post a small demo maybe?

cheers


AbbaRue(Posted 2004) [#66]
Has anyone tried any type of outdoor terrain with Tok yet?
I was woundering if it is fast at rendering a large terrain.
If someone has could you upload a demo of how it's done.


Robert(Posted 2004) [#67]
I was woundering if it is fast at rendering a large terrain.


Eh? Tokamak doesn't do any rendering at all. It does physics calculations on meshes.


AbbaRue(Posted 2004) [#68]
Tokamak has Terrain functions. The web site has a tutorial that creates a terrain. Here is the link:

http://www.adamdawes.com/programming/tokamak/04_TerrainMesh.html
I wanted to know how to do this in blitz3d with the Tok interface.


Bot Builder(Posted 2004) [#69]
maybe he means doing physics calcs on large terrains. I'm pretty sure its fast enough for most things your going to be doing. certaintly faster than a renderer. If it becomes a problem then you can use a lower triangle equivalent of the render mesh for physics.


Ice9(Posted 2004) [#70]
Here's a little sheep herding demo based off of Toms Galloping code. Maybe you coud make the sheep gallop ;)

Arrow keys move the sheep dog

;sheep herder based on Toms code
;Arbitrage



; Joint tests, trying to simulate vehicle axles
;
; I got a galloping car instead hehe
;
; Scouse

Const FPS=50


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

WireFrame False

Const ENTS=200

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

TOKSIM_CreateSimulator(ENTS,5,0,-10,0)

ground = CreateCube()
EntityColor ground,5,5,55 
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)

wall1 = CreateCube()
EntityColor wall1,25,25,55 
ScaleEntity wall1,2,10,50 
PositionEntity wall1,50,0,0
abwall1 = TOKAB_Create()
TOKAB_AddBox(abwall1,4.0,20.0,100.0)
TOKAB_SetPosition(abwall1,50.0,0,0.0)

wall2 = CreateCube()
EntityColor wall2,25,25,55 
ScaleEntity wall2,2,10,50 
PositionEntity wall2,-50,0,0
abwall2 = TOKAB_Create()
TOKAB_AddBox(abwall2,4.0,20.0,100.0)
TOKAB_SetPosition(abwall2,-50.0,0,0.0)

wall3 = CreateCube()
EntityColor wall3,25,25,55 
ScaleEntity wall3,50,10,2 
PositionEntity wall3,0,0,-50
abwall3 = TOKAB_Create()
TOKAB_AddBox(abwall3,100.0,20.0,4.0)
TOKAB_SetPosition(abwall3,0.0,0,-50.0)

wall4 = CreateCube()
EntityColor wall4,25,25,55 
ScaleEntity wall4,50,10,2 
PositionEntity wall4,0,0,50
abwall4 = TOKAB_Create()
TOKAB_AddBox(abwall4,100.0,20.0,4.0)
TOKAB_SetPosition(abwall4,0.0,0,50.0)


Dim obj(ENTS)
Dim rb(ENTS)

  obj(1) = CreateCube()
  ScaleEntity obj(1),.5,.5,.5 
  rb(1) = TOKRB_Create()
  TOKRB_AddBox rb(1),1.0,1.0,1.0
  ;TOKRB_CollideConnected rb(1),True
  TOKRB_SetPosition rb(1),0,2,0
  PositionEntity obj(1),0,2,0
  TOKRB_SetLinearDamping rb(1),0.05
  TOKRB_SetAngularDamping rb(1),0.05 	
  TOKRB_SetMass rb(1),2.0
  TOKRB_SetBoxInertiaTensor rb(1),1,1,2,2.0 
Xpos =-20
Zpos =-10
For x = 2 To 200 
	Xpos=Xpos +2
	If Xpos>20
		Zpos=Zpos +2
		Xpos=-20
		If ZPos > 10 Then Zpos=-10
	EndIf
	
	  obj(x) = CreateCube()
	  ScaleEntity obj(x),.5,.5,.5 
	  rb(x) = TOKRB_Create()
	  TOKRB_AddBox rb(x),1.0,1.0,1.0
	  ;TOKRB_CollideConnected rb(1),True
	  TOKRB_SetPosition rb(x),Xpos,2,Zpos
	  PositionEntity obj(x),Xposx,2,Zpos
	  TOKRB_SetLinearDamping rb(x),0.01
	  TOKRB_SetAngularDamping rb(x),0.01 	
	  TOKRB_SetMass rb(x),2.0
	  TOKRB_SetBoxInertiaTensor rb(x),1,1,2,2.0  
Next
  ;obj(i) = CreateCylinder()
  ;rb(i) = TOKRB_Create()
  ;TOKRB_AddCylinder rb(i),2.0,1.0
  ;TOKRB_SetPosition(rb(i),x#,2+i*0.2,z#)
  ;TOKRB_SetAngularDamping rb(i),0.02 
  ;TOKRB_SetLinearDamping rb(i),0.001 
  ;TOKRB_SetMass rb(i),2.0
  ;TOKRB_SetCylinderInertiaTensor rb(i),2.0,1.0,2.0  


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

  



Centerpivot = CreatePivot()

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

rot#=0

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

imptime=MilliSecs()
; 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.0/FPS)

If rot#>360 Then rot#=0

;PositionEntity camera,camx#,40,camz#

PositionEntity camera,EntityX(obj(1)),EntityY(obj(1))+15,EntityZ(obj(1))-+10
PointEntity camera,obj(1)  
	UpdateWorld

	Next

; Not sure wether to put this here or inside the for/next above...
For i=1 To 200
 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

If KeyDown(200) Then
 TOKRB_ApplyImpulse rb(1),0,0,5*ticks
EndIf
If KeyDown(208) Then
 TOKRB_ApplyImpulse rb(1),0,0,-5*ticks
EndIf

If KeyDown(205) Then
 TOKRB_ApplyImpulse rb(1),5*ticks,0,0
EndIf
If KeyDown(203) Then
 TOKRB_ApplyImpulse rb(1),-5*ticks,0,0
EndIf


RenderWorld tween

Text 0,0,"Physics Time:"+TOKSIM_GetPhysicsTime()*1000.0+ " milliseconds"
Text 0,10,"Render Time:"+Str(elapsed)+ " milliseconds"
	Flip False

Wend

TOKSIM_DestroySimulator()

End



bradford6(Posted 2004) [#71]
rmb = place rigid body
lmb = apply force
lmb + ctrl = apply lots of force

wasd + mouselook t 'fly'

;# TOKAMAK DEMO v7 (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
; thanks to fredborg for the maketokcollider func


Graphics3D 800,600,0,2
Global midw = GraphicsWidth()/2
Global midh =GraphicsHeight()/2
SetBuffer BackBuffer()
HidePointer 
WireFrame False

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

Global campiv = CreatePivot()
Global camera = CreateCamera(campiv)
Global pickmarker = CreateSphere(4)
EntityAlpha pickmarker,.75
Global pictentity,pnx#,pny#,pnz#,pcx#,pcy#,pcz#
Global latspeed#,speed#,MX#,MY#

Global TOKS
CameraClsColor(camera,20,20,205)


TOKSIM_CreateSimulator(ENTS,1,0,-10,0)

; go and create a generic checkerboard texture to apply to the objects
cubetex = create_cube_texture()
spheretex = create_sphere_texture()
cyltex = create_cyl_texture()
worldtex = create_world_texture()



world = CreateCube()
EntityPickMode world,2
sc# = 50
ScaleMesh world,sc#,sc#,sc#
PositionMesh world,0,sc#,0
FlipMesh world
EntityTexture world,worldtex
maketokcollider(world)


Dim obj(ENTS)
Dim rb(ENTS)

SeedRnd MilliSecs()  


; add--------------------------------------------------------------------------


	;create_TOK_BOX(xs#,ys#,zs#,xp#,yp#,zp#,damp#,angdamp#,mass#,iw#,ih#,id#,imass#, texture)
	;create_TOK_BOX(8,1,8,0,5,0,0.0025,.125,4,cubetex)
	xs#=32 iw#=xs#
	ys#=1 ih#=ys#
	zs#=8 id#=zs#	
	mass# = 2 imass# = mass#

	
	
	create_TOK_BOX(xs#,ys#,zs#,0,6,0,0.001,0.002,mass#,8,3,8,imass#,cubetex,"box")

	;create_TOK_BALL(segs,sc#,xp#,yp#,zp#,angdamp#,lindamp#,mass#,IT1#,IT2#)
	; # create tokamak sphere
	create_TOK_BALL(7,4,0,4,-4,0.002,0.001,2.0,1.0,.5,spheretex,"ball")
	create_TOK_BALL(7,4,0,4,4,0.002,0.001,2.0,1.0,.5,spheretex,"ball2")

	;TOKRB_SetTorque(rb(toks),5,0,0)
	joint1 = TOKJOINT_Create(2,rb(toks-2),rb(toks-1))
	TOKJOINT_SetType(joint1,1)
	TOKJOINT_SetPositionWorld(joint1,0,4,-4)
	TOKJOINT_Enable(joint1,True)
	
	joint2 = TOKJOINT_Create(2,rb(toks-2),rb(toks))
	TOKJOINT_SetType(joint2,1)
	TOKJOINT_SetPositionWorld(joint2,0,4,4)
	TOKJOINT_Enable(joint2,True)
	
	;joint3 = TOKJOINT_Create(1,rb(toks),0)
	;TOKJOINT_SetType(joint3,1)
	;TOKJOINT_SetPositionWorld(joint3,0,0,8)
	;TOKJOINT_Enable(joint3,True)

	;joint4 = TOKJOINT_Create(1,rb(toks-1),0)
	;TOKJOINT_SetType(joint4,1)
	;TOKJOINT_SetPositionWorld(joint4,0,0,-8)
	;TOKJOINT_Enable(joint4,True)


	
	;create_TOK_CYL(segs,,height#,radius#,xp#,yp#,zp#,angdamp#,lindamp#,mass#,IT1#,IT2#,IT3#,texture)
	create_TOK_BALL(12,4,0,6,0,0.002,0.001,2.0,1.0,.5,spheretex,"ball3")
	
	
	create_TOK_BOX(4,2,4,0,8,0,0.001,0.002,2,2,2,2,imass#,cubetex,"box2")
	
	create_TOK_BOX(2,2,2,0,8,-4,0.01,0.0002,2,2,2,2,imass#,cubetex,"box3")

			 
   			
	 
	
	
	 


; add--------------------------------------------------------------------------

Centerpivot = CreatePivot()

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

rot#=0

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

imptime=MilliSecs()

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

;rot#=rot#+0.05

If rot#>360 Then rot#=0

PositionEntity campiv,camx#,40,camz#
PointEntity campiv,centerpivot  


; +++ MAIN LOOP START ++++++ MAIN LOOP START ++++++ MAIN LOOP START ++++++ MAIN LOOP START +++
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)

move_camera()

	UpdateWorld

	Next

; Not sure wether to put this here or inside the for/next above...
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

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

 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

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,"pitch:"+EntityPitch(campiv)
;Text 0,50,"Render Time:"+Str(elapsed)+ " milliseconds"

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_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,height#,radius#,xp#,yp#,zp#,angdamp#,lindamp#,mass#,IT1#,IT2#,IT3#,texture)

			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),height#,radius#
			  ScaleEntity obj(TOKS),radius#/1.95,height#,radius#/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),IT1#,IT2#,IT3#  
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
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 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_SetTerrainMesh vertices,ttlvert,triangles,ttltris
 ; Now we can free the banks as Tokamak has copied all data
 FreeBank vertices
 FreeBank triangles
End Function



(tu) sinu(Posted 2004) [#72]
maybe a dumb question but can we now use tokamak for collisions instead of blitz ones?


aCiD2(Posted 2004) [#73]
yea, no reason why not. :) but, there is no way to make a rigid body have something like tokrb_addmesh ...


AbbaRue(Posted 2004) [#74]
I was wondering if someone could rewrite the demo file at:
http://www.adamdawes.com/programming/tokamak/04_TerrainMesh.html
So it will work in Blitz3d.


Bot Builder(Posted 2004) [#75]
Haven't we allready? all you need to do is pop in a terrain mesh along with a bunch of spheres. check out the latest version of bradford's demo.


DarkEagle(Posted 2004) [#76]
hey sweenie, do you plan on implenting constraints/collision respone info anytime soon?


Tom(Posted 2004) [#77]
Lots of stuff in the works :)

http://www.blitzbasic.com/logs/userlog.php?user=285


slenkar(Posted 2004) [#78]
Hi im a bit of a newb to all this, in my game I have a limit of 200 entities before my game starts to slow down but in a demo of TOKAMAK physics it could only handle 100 rigid bodies before it slowed down.
Would it be wise for me to used TOKAMAK with my game??


Tom(Posted 2004) [#79]
Depends on how complex the simulation is, or what spec PC you run the game on?

As with general graphics detail, scale the amount of realtime physics used based on a 'low, medium, high' setting.

Even 20 realistic moving entities would be better than none :)

Tom


Bot Builder(Posted 2004) [#80]
I believe the only prob. with 200 entities is memory use. if that's just a precaution, and the entity level isn't likely to go up to that then you should have no prob. And also, 200 entities isn't to unreasonable. Most of your time is lost in rendering those 200 entitities, which is probably one of the reasons the Tokamak demos are slow. If your game requires physics, then you aren't gonna get much faster without creating a dll in some other lang(C most likely).


slenkar(Posted 2004) [#81]
Ive got a slow system 600MHZ and 64MB of ram with onboard graphics, All I need to know is , is Tokamak faster at doing collisions and reactions to collisions?? Or is it just easier to program with Tokamak.


bradford6(Posted 2004) [#82]
slenkar,
the best way to answer your question is to test it yourself. here is what I would do.

create a tokamak simulation with 1000 rigid bodies.
do not render the blitz entities and see how fast it is.


my observations:

the number of polygons is not the confounding factor. in fact, you could have a single surface mesh with 100,000 polygons render at a reasonable rate.

the bottleneck seems to be:
1. materials: the number of surfaces and textures
2. entity count. the number of entities

to have a great looking scene, I recommend using fewer entities with fewer materials. use your polygons to add detail, rather than extra texturemaps.


LostCargo(Posted 2004) [#83]
i guess a better question is the collision setup better than blitz3d?


Bot Builder(Posted 2004) [#84]
Depends on how you look at it. seems to me that tokamak has a better collision setup as far as functions cause it does oriented capsules, boxes, and spheres. however, there are some problems with falling through terrains every once in a while :(


Sweenie(Posted 2004) [#85]
The reason bodies fall through a terrain is mostly due to high velocities combined with high timesteps.
So either increase accuracy by using smaller timesteps or lower your velocities.
Animated bodies doesn't suffer as much of this as an animated body has some volume/thickness while a terrain triangle has no volume/thickness at all.

Tokamaks collisionssystem doesn't perform any sweep-tests so if a body is just above a terrain triangle at one frame and in the next frame it passes completely through, Tokamak won't detect any collision.

I guess the bodies can fall through an animated body too if it's very very thin.

One way to make sure that bodies doesn't reach too high velocities is to set the lineardamping a little higher, but not too much or the body will seem like it's falling through water.
And remember that gamephysics doesn't necessarily need to be realistic, just look realistic.


bradford6(Posted 2004) [#86]
the beauty of Tokamak is that it is configurable. You can be super-realistc or do a best effort simulation that trades accuracy for performance. If it looks ight, then it is right. We arent building satellites here.

the only time i see an RB fall through the world is when it is going extremely fast (like sweenie said) ask yourself, How fast do my rigid bodies need to go?


LostCargo(Posted 2004) [#87]
i guess its not a good idea to do bullets with tokamak. i mean calculating richochets and bullet deformation... not something that really matters. lol


bradford6(Posted 2004) [#88]
bullets, no but cannonballs and lower velocity projectiles work great.


Sweenie(Posted 2004) [#89]
Ok, jointlimits and some other new functions are implemented.
Let's make some ragdolls!

Get the update at my page.
www.freewebs.com/sweenie


aCiD2(Posted 2004) [#90]
smoooooooth :D


RetroBooster(Posted 2004) [#91]
great :)


RayTracer(Posted 2004) [#92]
wicked


Bot Builder(Posted 2004) [#93]
saweet! yay. jointlimits..... I assume it's backwards compatible?


Tom(Posted 2004) [#94]
Sweenie:

Great work !!!!!!!!!!1

Cheers
Tom


bradford6(Posted 2004) [#95]
AWESOME Sweenie!!!

bot. it is not backwards compatible, but I was able to fix my code in about 10 minutes.
just fix onr thing and run....blitz will tell you what you need to fix.


Rimmsy(Posted 2004) [#96]
did you restart your blitz ide?


bradford6(Posted 2004) [#97]
yes. restart the ide after you put the wrapper in your userlibs. (it gets the highlighting from the decls)


Bot Builder(Posted 2004) [#98]
yeah... I didn't see the front page :) no biggy.


Tom(Posted 2004) [#99]
ragdoll demos up!

Unfortunately I only have about 45 meg of bandwidth left on my webby and my ISP webspace is flakey, so if anyone can mirror the file until I sort my webby out, please feel free!

http://www.tomspeed.com/RagOrkDemos.zip

Cursors plus what's on screen to interact, also in demo 2 'v' toggles rigidbody visibility.

There's no reset in it 'yet'.

cya!
Tom


Bouncer(Posted 2004) [#100]
That's really cool...


bradford6(Posted 2004) [#101]
very cool,
can you show us the source?


dangerdave(Posted 2004) [#102]
Good stuff Tom!
What did you use to model the Ork?
How did you get the data that you needed?

====================
NOTE: I uploaded Tom's demo to my site!

Please go to http://www.stewartsoftware.ca/downloads/RagOrkDemos.zip


Bot Builder(Posted 2004) [#103]
fantastic. I really like the second one. nice orc aswell. great anims :P.

codez? or should I email you?


Tom(Posted 2004) [#104]
bradford, bot builder:

I'm working on an basic editor for setting up rigs, and I've learnt a few things on the way. The editor is simple, is suited to editing data for 'runtime ragdoll creation', and works like so:

Load your animated B3D file.

Default box type rigid bodies are added to each bone, and a small sphere at the Bones base position. (to aid in picking joint positions).

To simplify a rig, delete any rigid bodies you don't need. This works fine as later on when setting up the ragdoll at runtime, any Bone that has an associated rigidbody gets unparented (it needs to be unparented because it's positon/rotation is controled by the RigidBody it's associated to), but those without will remain parented. i.e You may decide hands may not need to be animated by the ragdoll, so they remain parented to the forearm, which will be animated by the ragdoll.

Switch to a Joint setup mode, using the left & right mouse buttons, select 2 rigidbodies, then while holding a key, click on the Bone sphere to set the joints world position.

Resize & change the rigidbody types interactively to best fit your model.

Save out the rigidbody & joint data, done!

There's some other stuff I need to add like limits, and setting a joint frame world (as soon as Sweenie explain how the hell it works! hehe)


If you can bear to read the following...

As I understand it, the basic joint creation command automaticaly sets up the alignment of your joints 'cone limits' based on the rotation of the rigid body at the time you create the joint (phew!), while this is a nice feature it may not be appropriate for creating ragdolls on the fly (as in the demo).

The reason being, in the editor, the default pose of your character is used while editing. Imagine the arms are in a classic 'T' pose, looking at that, you'll want the arms to have free movement of about 45 degrees up/down/front/back coming off the shoulder, right?

But what if you characters arm is pointing down to it's side as you initialise a ragdoll setup at runtime?...then, the alignment of the 'cone limits' axis will be down too, so the arms will never be able to move above above the shoulders, hmm :|

That's where (I think) the FrameWorldA .. B commands are used. With those, you can define the Axis the limits will apply from.

I guess I could have said that the default joint creation command creates its limits on an Axis 'local to the Bone/rigidbody' :)

Sweenie please correect me if I'm wrong!

dangerdave:
I used Lightwave to model & animate the Ork. and thanks for mirroring the demo! :)

Editor will be out in a few days!

Cya!
Tom

Freelance 3D Artist, full time dad.


Tom(Posted 2004) [#105]
Sweenie:

I'm wondering if the CollideConnected command does actualy tell a rigid body that it CAN collide with direct neighbours?

I was sure I read that can't happen on the Tokamak forums but If I have it set to True for joints in my ragdolls, they just fly off the screen like superman as soon as I activate them :)

Some of the ragdoll rigid bodys in my demo above do intersect slightly, so I'm guessing that's what's happening. Any ideas?

Tom


Mustang(Posted 2004) [#106]
Gheeeez Tom! Those Orc demos were really mind blowing! I have missed the whole Tokamak-thingy because I've been so busy otherwise... this was the first Tokamak-demo I tried and it RULES! Sure could use something like this in my game too... now I have to read every god damn post regarding Tokamak... and there's quite a few of them! Any schedule / ETA when you have working editor, Tom?

[edit]

Editor will be out in a few days!


Ah - Cool! :)


Sweenie(Posted 2004) [#107]
To tell you the truth I haven't quite grasped how the limits work either.
It's very hard to visualise them in your head, but I was hoping your editor would fix that. ;)

I think I understand what you mean regarding the arm, and I do think you're right about the SetJointPositionFrameA & B.
In your case FrameA is the shoulder and Frame B is the arm.
FrameA can have the same rotation, but FrameB should have an initial rotation of 45 degrees to compensate for the arm being down.
I just realized that I forgot to implement rotation of FrameA&B.
Will fix this tonight.


Sweenie(Posted 2004) [#108]
Some of the ragdoll rigid bodys in my demo above do intersect slightly, so I'm guessing that's what's happening. Any ideas?



I've never managed to get direct neighbours to collide but if two bodies that are not directly neighbours are brought together somehow with joints causing them to intersect, there will be a struggle between the collisionsystem and the jointsolver.
The collision will try to push them apart while the joints try to bring them together and eventually you will get a rigidbody "explosion".


CyBeRGoth(Posted 2004) [#109]
Cool update!

Would any of the new commands help me with my rotating ball problem? You know so you can rotate a ball left or right (yaw) and have it move forward in the direction it is facing? Someone sudgested Tformvector but thats maths.. and me and maths dont add up :

Cheers

ps.. someone make a ball demo where the arrow keys are used to rotate the ball.... go on :P


simonh(Posted 2004) [#110]
Try rotating the mesh with RotateMesh, and then just moving the entity.

Amazing demo by the way Tom and great work with the new update Sweenie!


bradford6(Posted 2004) [#111]
Car demo. still very buggy. use arrows to drive. you can move the camera around with wasd + mouse

this is a car made from a box with cylinders attached to the rear wheels with hingjoints and independent axles on the front. the front wheels go a little buggy every now and again.

have a look...(this is v3 wrapper code)


;# TOKAMAK car 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, 


Graphics3D 800,600,0,2
Global midw = GraphicsWidth()/2
Global midh =GraphicsHeight()/2
SetBuffer BackBuffer()
HidePointer 
WireFrame False

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

Global campiv = CreatePivot()
Global camera = CreateCamera(campiv)
Global pickmarker = CreateSphere(4)
EntityAlpha pickmarker,.75
Global pictentity,pnx#,pny#,pnz#,pcx#,pcy#,pcz#
Global latspeed#,speed#,MX#,MY#

Global TOKS
CameraClsColor(camera,0,0,0)


TOKSIM_CreateSimulator(ENTS,1,0,-10,0)

; go and create a generic checkerboard texture to apply to the objects
cubetex = create_cube_texture()
spheretex = create_sphere_texture()
cyltex = create_cyl_texture()
worldtex = create_world_texture()


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


maketokcollider(world)
;maketokcollider(obstacle)

Dim obj(ENTS)
Dim rb(ENTS)

SeedRnd MilliSecs()  


; add--------------------------------------------------------------------------

.cardata
	;create_TOK_BOX(xs#,ys#,zs#,xp#,yp#,zp#,damp#,angdamp#,mass#,iw#,ih#,id#,imass#, texture)
	;create_TOK_BOX(8,1,8,0,5,0,0.0025,.125,4,cubetex)
	carwidth#=2 iw#=carwidth#
	carheight#=4 ih#=carheight#
	carlength#=4 id#=carlength#	
	mass# = .5 imass# = mass#
	
	wheelwidth# = 2.5
	wheellength# = 3.5
	wheelclearance# = 2
	wheelheight# = 0.5 ; thickness
	wheeldiameter# = 4 ; tall-ness
	carx# = 2
	cary# = 5
	carz# = 2
	
	; OBJ-1
	create_TOK_BOX(carwidth#,carheight#,carlength#,carx#,cary#,carz#,0.001,0.001,mass#,iw,ih,id,imass,cubetex,"car")

	;create_TOK_BALL(segs,sc#,xp#,yp#,zp#,angdamp#,lindamp#,mass#,IT1#,IT2#)
	; # create tokamak sphere
	
	; ----------------------------------------------------------------------------------

	id#=2
	ih#=3
	iw#=1
	;zs#=1 id#=zs#	
	mass# = 1
	imass# = 1
	
	rearwheelmass# = 3
	angdampfront#= 0.002
	angdamprear# = 0.001
	lindampfront# = 0.002
	lindamprear# = 0.001
	segs = 16
	
	axleiw#=1 axleih#=0.25 axleid#=1 
	
	axlemass# = 1.5
	axleimass# = 1.5
For c = 1 To 4
	Select c
		Case 1 : cx# = carx#-(carwidth#/1.5) : cy# = cary#-(carheight#/2) : cz# = carz#+(carlength#/1.5) : wheelname$ = "leftfront" : inc = 1
					
					; obj 2
					create_TOK_BOX(1.5,.5,1,cx#,cy#,cz#,0.001,0.01,axlemass#,axleiw,axleih,axleid,axleimass,cubetex,"car")

					;obj 3
					create_TOK_CYL(segs,wheeldiameter#,wheelheight#,cx#-1,cy#,cz#,angdampfront#,lindampfront#,mass#,Id#,ih#,imass#,spheretex,wheelname$)
					;create_TOK_ball(segs,wheeldiameter#,cx#-1,cy#,cz#,angdampfront#,lindampfront#,mass#,Id#,imass#,spheretex,wheelname$)
					

					;create_TOK_ball(5,wheelsize#,carx#-wheelheight#,cary#-wheelwidth#,carz#+wheellength#,angdamp#,lindamp#,mass#,Id#,imass#,spheretex,"leftfront")
					EntityColor obj(2),155,0,0 
					EntityColor obj(3),255,0,0 ; red = 
					TOKRB_SetRotation(rb(toks),0,00,90)
					;TOKRB_SetTorque(rb(toks),5,0,0)
					
					; axle
					joint1a = TOKJOINT_Create(2,rb(1),rb(2))
					TOKJOINT_SetType(joint1a,3)
					TOKJOINT_SetPositionAndRotationWorld(joint1a,cx#,cy#,cz#,0,0,0)
					TOKJOINT_Enable(joint1a,True)
					TOKJOINT_SetLowerLimit joint1a,-3.14*0.50 ; (-45 degrees)
					TOKJOINT_SetUpperLimit joint1a,3.14*0.50  ; (+45 degrees)
					TOKJOINT_EnableLimit joint1a,True  

					; wheel
					joint1b = TOKJOINT_Create(2,rb(2),rb(3))
					TOKJOINT_SetType(joint1b,3)
					TOKJOINT_SetPositionAndRotationWorld(joint1b,cx#-1,cy#,cz#,0,0,90)
					TOKJOINT_Enable(joint1b,True)
					TOKJOINT_SetJointLength(Joint1b,3)
					TOKJOINT_SetLowerLimit2 joint1b,-3.14*0.1 ; (-45 degrees)
					TOKJOINT_SetUpperLimit2 joint1b,3.14*0.1  ; (+45 degrees)
					TOKJOINT_EnableLimit2 joint1b,True  

		Case 2 : cx# = carx#+(carwidth#/1.5) : cy# = cary#-(carheight#/2) : cz# = carz#+(carlength#/1.5) : wheelname$ = "rightfront" : inc = 2
					
					
					; obj 4
					create_TOK_BOX(1.5,.5,1,cx#,cy#,cz#,0.001,0.01,axlemass#,axleiw,axleih,axleid,axleimass,cubetex,"car")

					; obj 5
					create_TOK_CYL(segs,wheeldiameter#,wheelheight#,cx#+1,cy#,cz#,angdampfront#,lindampfront#,mass#,Id#,ih#,imass#,spheretex,wheelname$)
					;create_TOK_ball(segs,wheeldiameter#,cx#+1,cy#,cz#,angdampfront#,lindampfront#,mass#,Id#,imass#,spheretex,wheelname$)
					

					;create_TOK_ball(5,wheelsize#,carx#-wheelheight#,cary#-wheelwidth#,carz#+wheellength#,angdamp#,lindamp#,mass#,Id#,imass#,spheretex,"leftfront")
					EntityColor obj(4),0,255,0 ; green= 
					EntityColor obj(5),0,120,0
					TOKRB_SetRotation(rb(toks),0,00,90)
					;TOKRB_SetTorque(rb(toks),5,0,0)
					
					; axle
					joint2a = TOKJOINT_Create(2,rb(1),rb(4))
					TOKJOINT_SetType(joint2a,3)
					TOKJOINT_SetPositionAndRotationWorld(joint2a,cx#,cy#,cz#,0,0,0)
					TOKJOINT_Enable(joint2a,True)
					TOKJOINT_SetLowerLimit joint2a,-3.14*.5 ; (-45 degrees)
					TOKJOINT_SetUpperLimit joint2a,3.14*0.5  ; (+45 degrees)
					TOKJOINT_EnableLimit joint2a,True  

					; wheel
					joint2b = TOKJOINT_Create(2,rb(4),rb(5))
					TOKJOINT_SetType(joint2b,3)
					TOKJOINT_SetPositionAndRotationWorld(joint2b,cx#+1,cy#,cz#,0,0,90)
					TOKJOINT_Enable(joint2b,True)
					TOKJOINT_SetJointLength(Joint2b,.1)
					TOKJOINT_SetLowerLimit2 joint2b,-3.14*0.1 ; (-45 degrees)
					TOKJOINT_SetUpperLimit2 joint2b,3.14*0.1  ; (+45 degrees)
					TOKJOINT_EnableLimit2 joint2b,True  


	

		Case 3 : cx# = carx#-(carwidth#) : cy# = cary#-(carheight#/2) : cz# = carz#-(carlength#/1.5) : wheelname$ = "leftrear" : inc = 3
					; obj 6
					create_TOK_CYL(segs,wheeldiameter#,wheelheight#,cx#,cy#,cz#,angdamprear#,lindamprear#,rearwheelmass#,Id#,ih#/2,rearwheelmass#*2,spheretex,wheelname$)
					;create_TOK_ball(segs,wheeldiameter#,cx#,cy#,cz#,angdampfront#,lindampfront#,mass#,Id#,imass#,spheretex,wheelname$)
					

					EntityColor obj(6),255,0,0 ; blue= 
					TOKRB_SetRotation(rb(toks),0,00,90)
					;TOKRB_SetTorque(rb(toks),5,0,0)
					joint3 = TOKJOINT_Create(2,rb(1),rb(6))
					TOKJOINT_SetType(joint3,3)
					TOKJOINT_SetPositionAndRotationWorld(joint3,cx#,cy#,cz#,0,0,90)
					TOKJOINT_Enable(joint3,True)
	

		Case 4 : cx# = carx#+(carwidth#) : cy# = cary#-(carheight#/2) : cz# = carz#-(carlength#/1.5) : wheelname$ = "rightrear" : inc = 4
					; obj 7
					create_TOK_CYL(segs,wheeldiameter#,wheelheight#,cx#,cy#,cz#,angdamprear#,lindamprear#,rearwheelmass#,Id#,ih#/2,rearwheelmass#*2,spheretex,wheelname$)
					;create_TOK_ball(segs,wheeldiameter#,cx#,cy#,cz#,angdampfront#,lindampfront#,mass#,Id#,imass#,spheretex,wheelname$)
					

					
					EntityColor obj(7),255,0,0 ; yellow= 
					TOKRB_SetRotation(rb(toks),0,00,90)
					;TOKRB_SetTorque(rb(toks),5,0,0)
					joint4 = TOKJOINT_Create(2,rb(1),rb(7))
					TOKJOINT_SetType(joint4,3)
					TOKJOINT_SetPositionAndRotationWorld(joint4,cx#,cy#,cz#,0,0,90)
					TOKJOINT_Enable(joint4,True)
	

	
	End Select
	
	

Next
	; ----------------------------------------------------------------------------------

For columns = 1 To 4
	For rows = 1 To 4
	
		create_TOK_BOX(4,4,4,(columns*4)+20,rows*4,16,0.001,0.001,1.5,4,4,4,2,cubetex,"car")
	Next
Next

; ----------------------------------------------------------------------------------




; add--------------------------------------------------------------------------

Centerpivot = CreatePivot()

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

rot#=0

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

imptime=MilliSecs()

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

;rot#=rot#+0.05

If rot#>360 Then rot#=0

PositionEntity campiv,camx#,40,camz#
PointEntity campiv,centerpivot  

FlushMouse 
; +++ 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

	Next

; Not sure wether to put this here or inside the for/next above...
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


.carmovement
;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
								
				TOKRB_ApplyTwist(rb(6),caryaw_cos#*force#,0,caryaw_sin#*force#)
				TOKRB_ApplyTwist(rb(7),caryaw_cos#*force#,0,caryaw_sin#*force#)
				force# = 6
				;TOKRB_ApplyImpulse rb(1),-(Sin(EntityYaw(obj(1)))*force#),-(Sin(EntityPitch(obj(1)))*force#),Cos(EntityYaw(obj(1)))*force#
	EndIf

	If KeyDown(208) = 1
				TOKRB_SetAngularMomentum(rb(6),caryaw_cos#*force#,0,caryaw_sin#*force#)
				TOKRB_SetAngularMomentum(rb(7),caryaw_cos#*force#,0,caryaw_sin#*force#)
				force# = -4

	EndIf
	
		
	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)

 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

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_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 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



DarkEagle(Posted 2004) [#112]
any idea why this goes insane?

Const FPS=50


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

WireFrame False

Const ENTS=10

Global cam = CreateCamera()
PositionEntity cam,0,10,-50

TOKSIM_CreateSimulator(ENTS,5,0,-10,0)


Dim obj(ENTS)
Dim rb(ENTS)

SeedRnd MilliSecs()  


For i = 1 To ents

	obj(i) = CreateCube()
	rb(i) = TOKRB_Create()
	CreateTokCube(obj(i),rb(i),0,10-i*3,0,1,1,1,2)
	TOKRB_CollideConnected rb(i),1

Next

For i = 1 To ents-1

	joint = TOKJOINT_Create(2,rb(i),rb(i+1))
	TOKJOINT_SetType joint,1 
	TOKJOINT_SetPositionAndRotationWorld joint,0,9-i*3,0,90,0,0
	TOKJOINT_Enable joint,1
	TOKJOINT_SetLowerLimit joint,0
	TOKJOINT_SetUpperLimit joint,0
	TOKJOINT_EnableLimit joint,1
	TOKJOINT_SetLowerLimit2 joint,Pi*0.4
	TOKJOINT_SetUpperLimit2 joint,0
	TOKJOINT_EnableLimit2 joint,1

Next

joint = TOKJOINT_Create(1,rb(1),0)
TOKJOINT_SetType joint,1 
TOKJOINT_SetPositionAndRotationWorld joint,0,11,0,0,0,0
TOKJOINT_Enable joint,1



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



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

		TOKSIM_Advance(1.5/FPS,1)

		UpdateWorld
	Next

	; 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
	
	If KeyDown(57)
		TOKRB_ApplyImpulse rb(ents),1,1,1
	End If
	
	RenderWorld tween
	
	Text 0,0,"Physics Time:"+TOKSIM_GetPhysicsTime()*1000.0+ " milliseconds"
	Text 0,10,"Render Time:"+Str(elapsed)+ " milliseconds"


Flip False

Wend

TOKSIM_DestroySimulator()
End


Function CreateTokCube(entity,rb,x#,y#,z#,xs#=1.0,ys#=1.0,zs#=1.0,mass#=1.0)

	ScaleEntity entity,xs,ys,zs
	PositionEntity entity,x,y,z
	
	TOKRB_AddBox rb,xs*2,ys*2,zs*2
	TOKRB_SetPosition rb,x,y,z
	TOKRB_SetLinearDamping rb,0.001
	TOKRB_SetAngularDamping rb,0.001
	TOKRB_SetMass rb,mass
	TOKRB_SetBoxInertiaTensor rb,xs*2,ys*2,zs*2,mass

End Function


Function CreateTokSphere(entity,rb,x#,y#,z#,rad#=1.0,mass#=1.0)

	ScaleEntity entity,rad,rad,rad
	PositionEntity entity,x,y,z
	
	TOKRB_AddSphere rb,rad#*2
	TOKRB_SetPosition rb,x,y,z
	TOKRB_SetLinearDamping rb,0.001
	TOKRB_SetMass rb,mass
	TOKRB_SetBoxInertiaTensor rb,rad*2,rad*2,rad*2,mass

End Function


Function CreateTokCylinder(entity,rb,x#,y#,z#,rad#=1.0,height#=1.0,mass#=1.0)

	TOKRB_AddCylinder rb,rad*2,height
	TOKRB_SetPosition rb,x,y,z
	TOKRB_SetLinearDamping rb,0.001 
	TOKRB_SetAngularDamping rb,0.01 
	TOKRB_SetMass rb,mass
	TOKRB_SetCylinderInertiaTensor rb,rad*2,height,mass

End Function



DarkEagle(Posted 2004) [#113]
thought it would be a good idea to help sweenie out and document the commands for ourselves! ive started doing the first few, just hoping you lot will help carry on and complete this? possibly turn into html?

*** Simulator ***
TOKSIM_CreateSimulator%(RBCount%,ABCount%,GravityX#,GravityY#,GravityZ#)
RBCount = number of rigid bodies.
ABCount = number of animated bodies.
GravityX,Y,Z = amount of gravity applying in each direction.

TOKSIM_DestroySimulator()
Destroys the simulator at the end of the program

TOKSIM_Advance(timestep#,SubSteps%)
timestep = time used for calculations. larger value = larger mvements per update.
SubSteps = amount of steps to split timestep into. this should usually be 1.

TOKSIM_GetPhysicsTime#()

TOKSIM_SetStaticMesh(Vertices*,VertexCount%,Triangles*,TriangleCount%)

*** Rigid Body *** 
TOKRB_Create%()
TOKRB_Free(RigidBody%)
TOKRB_GetX#(RigidBody%)
TOKRB_GetY#(RigidBody%)
TOKRB_GetZ#(RigidBody%)
TOKRB_SetPosition(RigidBody%,X#,Y#,Z#)
TOKRB_GetPitch#(RigidBody%)
TOKRB_GetYaw#(RigidBody%)
TOKRB_GetRoll#(RigidBody%)
TOKRB_SetRotation(RigidBody%,Pitch#,Yaw#,Roll#)
TOKRB_AddBox%(RigidBody%,Width#,Height#,Depth#)
TOKRB_AddSphere%(RigidBody%,Diameter#)
TOKRB_AddCylinder%(RigidBody%,Diameter#,Height#)
TOKRB_UpdateBoundingInfo(RigidBody%)
TOKRB_SetBoxInertiaTensor(RigidBody%,Width#,Height#,Depth#,Mass#)
TOKRB_SetSphereInertiaTensor(RigidBody%,Diameter#,Mass#)
TOKRB_SetCylinderInertiaTensor(RigidBody%,Diameter#,Height#,Mass#)
TOKRB_SetMass(RigidBody%,Mass#)
TOKRB_SetLinearDamping(RigidBody%,Damping#)
TOKRB_SetAngularDamping(RigidBody%,Damping#)
TOKRB_IsIdle%(RigidBody%)
TOKRB_CollideConnected(RigidBody%,Connected%)
TOKRB_SetSleepingParameter(RigidBody%,sleepparam#)
TOKRB_Active(RigidBody%,Active%)
TOKRB_IsActive%(RigidBody%)
TOKRB_ApplyImpulse(RigidBody%,X#,Y#,Z#)
TOKRB_ApplyImpulse2(RigidBody%,X#,Y#,Z#,XPos#,YPos#,ZPos#)
TOKRB_ApplyTwist(RigidBody%,X#,Y#,Z#)
TOKRB_SetForce(RigidBody%,X#,Y#,Z#)
TOKRB_SetForce2(RigidBody%,X#,Y#,Z#,XPos#,YPos#,ZPos#)
TOKRB_SetTorque(RigidBody%,X#,Y#,Z#)
TOKRB_SetVelocity(RigidBody%,X#,Y#,Z#)
TOKRB_SetAngularMomentum(RigidBody%,X#,Y#,Z#)
TOKRB_GetVelocityX#(RigidBody%)
TOKRB_GetVelocityY#(RigidBody%)
TOKRB_GetVelocityZ#(RigidBody%)
TOKRB_GetAngularMomentumX#(RigidBody%)
TOKRB_GetAngularMomentumY#(RigidBody%)
TOKRB_GetAngularMomentumZ#(RigidBody%)
TOKRB_GetAngularVelocityX#(RigidBody%)
TOKRB_GetAngularVelocityY#(RigidBody%)
TOKRB_GetAngularVelocityZ#(RigidBody%)

*** Animated Body ***
TOKAB_Create%()
TOKAB_Free(AnimatedBody%)
TOKAB_SetPosition(AnimatedBody%,X#,Y#,Z#)
TOKAB_SetRotation(AnimatedBody%,Pitch#,Yaw#,Roll#)
TOKAB_AddBox%(AnimatedBody%,Width#,Height#,Depth#)
TOKAB_AddSphere%(AnimatedBody%,Diameter#)
TOKAB_AddCylinder%(AnimatedBody%,Diameter#,Height#)

*** Geometry ***
TOKGEOM_SetPositionAndRotation(Geometry%,X#,Y#,Z#,Pitch#,Yaw#,Roll#)

*** Joint ***
TOKJOINT_Create%(ConnectionType%,BodyA%,BodyB%)
TOKJOINT_Free%(Joint%)
TOKJOINT_SetType(Joint%,JointType%)
TOKJOINT_SetPositionAndRotationWorld(Joint%,X#,Y#,Z#,Pitch#,Yaw#,Roll#)
TOKJOINT_SetPositionFrameA(Joint%,X#,Y#,Z#)
TOKJOINT_SetPositionFrameB(Joint%,X#,Y#,Z#)
TOKJOINT_SetJointLength(Joint%,Length#)
TOKJOINT_GetJointLength#(Joint%)
TOKJOINT_Enable(Joint%,Enable)
TOKJOINT_IsEnabled%(Joint%)
TOKJOINT_SetUpperLimit(Joint%,Limit#)
TOKJOINT_SetLowerLimit(Joint%,Limit#)
TOKJOINT_SetUpperLimit2(Joint%,Limit#)
TOKJOINT_SetLowerLimit2(Joint%,Limit#)
TOKJOINT_GetUpperLimit#(Joint%)
TOKJOINT_GetLowerLimit#(Joint%)
TOKJOINT_GetUpperLimit2#(Joint%)
TOKJOINT_GetLowerLimit2#(Joint%)
TOKJOINT_EnableLimit(Joint%,Enabled%)
TOKJOINT_EnableLimit2(Joint%,Enabled%)
TOKJOINT_IsLimitEnabled%(Joint%)
TOKJOINT_IsLimit2Enabled%(Joint%)



bradford6(Posted 2004) [#114]
I have a doc file in the works as well.

anyone see my car code ? (above ^ )

need some input on that one...


Ricky Smith(Posted 2004) [#115]
I know that animated bodies are not influenced by tomakak - so what exactly is the use of an animated body ??

EDIT - question posted in BlitzTool forum.


Sweenie(Posted 2004) [#116]
@DarkEagle:
In what way does it go insane?

It only went "insane" for me when I only had Limit2(Twist) enabled, but that could be reduced a bit by setting the angulardamping to 0.01 instead of 0.001
Angulardamping prevents bodies from spinning extremly fast.
But maybe that wasn't what you meant.


PsychicParrot(Posted 2004) [#117]
Bradford ... the car demo is a great start, but there seems to be a real lack of friction in there between the ground and the wheels - since I haven't spend enough time with Sweenie's wrapper, I don't know how you go about changing that? Is there a friction setting or similar?


Tom(Posted 2004) [#118]
DarkEagle: You have Upper & Lower limits of 0 and 0, that's leaving no room for the joint to flex. Try increaming the mass too.


aCiD2(Posted 2004) [#119]
i have a proteanide userlib for takomak any one want it? it has the proper command docs like

;;; <summary>Creates the simulator</summary>

that sort of stuff, useful for proteanuses, not much else however :P


Sweenie(Posted 2004) [#120]
Unfortunately I was very busy last night so I didn't have much time with the wrapper.
But materials are in(friction and restitution) and Accuracysettings for jointsolvers.

@Tom:
hehe, I DID actually implement rotation of FrameA & B in v0.3.
Just forgot to update the Tokamak.decls file.
Change the following lines:
TOKJOINT_SetPositionFrameA(Joint%,X#,Y#,Z#):"_TOKJOINT_SetPositionFrameA@16"
TOKJOINT_SetPositionFrameB(Joint%,X#,Y#,Z#):"_TOKJOINT_SetPositionFrameB@16"
To -->
TOKJOINT_SetPositionAndRotationFrameA(Joint%,X#,Y#,Z#,Pitch#,Yaw#,Roll#):"_TOKJOINT_SetPositionFrameA@28"
TOKJOINT_SetPositionAndRotationFrameB(Joint%,X#,Y#,Z#,Pitch#,Yaw#,Roll#):"_TOKJOINT_SetPositionFrameB@28"


Tom(Posted 2004) [#121]
Yeah I noticed last night and added it, I may have to post a Q. to the Tokamak guys about the frame world stuff.

The editor is quite usable, that is, it can produce something that works, with relative ease. A few new things I discovered along the way:

When creating a runtime ragdoll, of all the Bones in your character, the Root bone (first child of a B3D animated mesh) must be unparented, the majority of the rest of the Bones get unparented too, although they don't all have too as I explained in my earlier post.

Basicly your Bones are taken over by Tokamak and unparented from the main mesh, you effectively leave the meshes 'pivot' at the position it was at the time of creating the ragdoll. But then I come across a problem, if that mesh pivot went out of the camera view your actual character polygons disappear, Blitz thinks it's off screen and hides them, regardless of wether the Bones are in camera view, the effect showed up as an invisible character smashing down a wall, spooky! :)

I thought what if when creating the ragdoll, after unparenting all the Bones, I parent the actual mesh/pivot to the Root bone using the Global flag. It works! Now the mesh pivot sticks to the ragdoll, so no more disappearing character. (parenting a mesh to it's bones...crazy!)

There could be a neat side effect to this, it could be easy to deactivate the ragdoll, reparent all the Bones so the hierarchy is identical to when you loaded the mesh, and then can carry on animating it with regular Blitz commands (providing the character aint been killed of course! hehe)

Imagine, B3D animation cycle.........character gets knocked down, falls off a ledge or whatever using Tokamak.......then it gets back up again and you carry on animating it. Hmmm the possibilities!

Idealy I'd like to have a few function calls to make it all transparent, something like:

myChar.Ragdoll=CreateRagdoll(Entity) ; physics take over
...
TOKRB_ApplyImpulse myChar\RigidBody\Chest,x,y,z ; get funky!
...
FreeRagdoll(myChar.Ragdoll) ; back to Blitz animatable control

Yum!

Anyways, I'll crack away at this editor so I have something for tomorrow night (I hope!)

Cya!
Tom


(tu) sinu(Posted 2004) [#122]

I thought what if when creating the ragdoll, after unparenting all the Bones, I parent the actual mesh/pivot to the Root bone using the Global flag. It works! Now the mesh pivot sticks to the ragdoll, so no more disappearing character. (parenting a mesh to it's bones...crazy!)

There could be a neat side effect to this, it could be easy to deactivate the ragdoll, reparent all the Bones so the hierarchy is identical to when you loaded the mesh, and then can carry on animating it with regular Blitz commands (providing the character aint been killed of course! hehe)

Imagine, B3D animation cycle.........character gets knocked down, falls off a ledge or whatever using Tokamak.......then it gets back up again and you carry on animating it. Hmmm the possibilities!



that is exactly what i wanted to try/do :).


bradford6(Posted 2004) [#123]
hey, lets start a new sticky thread for this...


Bot Builder(Posted 2004) [#124]
yeah. this ones to long for me :) How bout recording the old/new positions and rotions of the bones while animating, then when it starts tokamak, apply force impulses based on the velocity, or (old-new)*mass. this makes it so that if the charachter is running, the limbs will move based on the animation/movement of the charachter.


Tom(Posted 2004) [#125]
That's a possibility too, but not just position data. If you stepped back a few frames and created a vector of each bone, do a dotproduct with old & new positions you'll get an angle which you could somehow convert to a force value. Also do a crossproduct on the 2 vectors and you have the axis on which to apply the twist.


Bot Builder(Posted 2004) [#126]
?why find the angle? I thought all you need is rotational and velocity data? maybe you know best.


Tom(Posted 2004) [#127]
Yeah but the physics aren't active at the time of creation, as soon as the rigid bodies are created they have no velocity or angular momentum, that's why we need to find that stuff out from the bones e.t.c :)


Sweenie(Posted 2004) [#128]
It seems that I have made some mistakes in the code that rotates the joints.
I only checked straight angles like 90 degrees and so on, but last night when I implemented the functions TOKJOINT_GetPitch,Yaw n Roll I noticed that the rotational values wasn't what they should be.

It was easier to spot mistakes with the rotation of the bodies because you could see the mistake visually, but it's more difficult with the joints.

But don't worry, I'm on it.


@Tom:
That could explain why you had problems setting up the joints. ;p


Ricky Smith(Posted 2004) [#129]
All credit to you Sweenie - you've done a marvellous job - considering the speed at which you have been pumping this stuff out !


bradford6(Posted 2004) [#130]
Sweenie,
Here is an idea. (If you havent already thought of it) create a joint_marker mesh that would visually identify the joint pitch,yaw,roll.

the best marker I have seen is the finned bones from 3dsmax. the fins really help you visualize the rotation of the bone


Sweenie(Posted 2004) [#131]
That is how I discovered the faulty values.
When I aligned the mesh used to mark the joint I saw that it went nuts.
But as Tom pointed out in the other forum, the values returned from the bodies aren't fully correct either.

But with a little help from the community I'm sure we get this fixed in notime. :)


bradford6(Posted 2004) [#132]
let me know how I can help.
(although I don't know a quaternion from a hole in the ground)


Hansie(Posted 2004) [#133]
is this the longest thread ever? :-D


skidracer(Posted 2004) [#134]
part 3 coming up...