Snooker / physics / conservating momentum ??????

Blitz3D Forums/Blitz3D Programming/Snooker / physics / conservating momentum ??????

cywhale(Posted 2004) [#1]
Hello everybody.

Trying to develope a snooker-like game/demo just for fun i ran into a big problem now.

Moving the balls around - no problem. Collision system is set up using blitz3d-commands.

Bouncing off walls - no problem so far.

The big, big problem now is the physics/ball to ball bouncing with momentum conservation.

Iīve read all board-topics at the bb3d-forum and other boards about that including the big "energy-loss-physics"-topic here where swifft was involved - helped me a lot understanding - but not to solve the problem.

I tried many different approaches, but none of them worked well. Sometimes the balls seem to surround each other before rolling the right way, sometimes they seem to "take a break" before rolling again, sometimes they just "explode" and do what they want. ;)
Tried all i could find including the many good demos in the code archives (2D and 3D), the code works well in the archive sources, but implemented into my code - nope, everytime a "near-but -not-enough" solution...

Right now i implemented just the code thatīs used for bouncing off walls - which doesent work well, too, for ball-2-ball.


I would be very,very glad if somebody can help me out here.
Maybe somebody can explain me the right way to ball-2-ball/momentum-conservation-physics?
Maybe any idea?

The complete code ready to run

;********************************************
;, SNOOKER DEMO
;********************************************

;PROBLEM:
	;* Conservating momentum / real ball to ball physics
	;* ball to ball bouncing code


;Environment 
Global screen_width=800
Global screen_height=600
Global mode_wire=0
Global mx#=0,my#=0
Graphics3D screen_width,screen_height,32,0

SetBuffer BackBuffer()

;Collision setup
Const col_world = 1
Const col_ball = 3
Const ball_gravity# = 10
Collisions col_ball,col_world,2,2
Collisions col_ball,col_ball,1,1

;ball definition
Type ball
	Field entity
	Field x#,y#,z#,xvel#,yvel#,zvel#
	Field mass#
	Field bounce#
	Field radius#
End Type

;Create balls
RndSeed
For i = 1 To 10
	CreateBall(Rnd(-1000,1000),57,Rnd(-1000,1000),Rnd(-180,50),0,Rnd(-18,180))
Next


;WORLD= Invisible Construct collision-box
Global world = CreateCube()
EntityType world,col_world
ScaleEntity world,2540,2000,1270 
MoveEntity world,0,2000,0
FlipMesh world
EntityAlpha world,0
UpdateNormals world

;Visible green table
Global table_plane=CreateCube()
ScaleEntity (table_plane,2540,1,1270)
EntityColor(table_plane,0,100,0)
MoveEntity(table_plane,0,-10,0)

;Camera setup
Global campiv = CreatePivot()
Global cam = CreateCamera(campiv)
CameraRange cam,0.01,10000
PositionEntity cam,0,800,-2000

;Light setup (just testing)
AmbientLight 150,150,150
Global spot1=CreateLight(3)
Global spot2=CreateLight(3)
Global spot3=CreateLight(3)
Global spot4=CreateLight(3)
PositionEntity spot1,-635,1500,-315
PositionEntity spot2,-635,1500,315
PositionEntity spot3,635,1500,315
PositionEntity spot4,635,1500,-315
PointEntity spot1,table_plane
PointEntity spot2,table_plane
PointEntity spot3,table_plane
PointEntity spot4,table_plane


;Main loop
While Not KeyHit(1)
	UpdateBalls(0.1)
	updateGame()
	UpdateWorld
	RenderWorld
	Flip(0)
Wend


;Creates new ball
Function CreateBall.ball(x#=0,y#=0,z#=0,xvel#=0,yvel#=0,zvel#=0)
	b.ball = New ball
	b\entity = CreateSphere()
	ScaleEntity b\entity,54,54,54
	EntityRadius b\entity,55,55
	EntityColor b\entity,Rand(28,255),Rand(28,255),Rand(28,255)
	EntityType b\entity,col_ball
	PositionEntity b\entity,x,y,z
	EntityShininess b\entity,1

	b\xvel# = xvel#
	b\yvel# = yvel#
	b\zvel# = zvel#

	b\x#=x#
	b\y#=y#
	b\z#=z#

	b\mass#=1
	b\bounce#=1
	b\radius#=27
	Return b
End Function


Function UpdateBalls(dt#=1)
	For b.ball = Each ball
		For i = 1 To CountCollisions(b\entity)
			HandleBalls(b.ball,i)
		Next	
		b\x#=b\x#+b\xvel#
		b\y#=b\y#+b\yvel#
		b\z#=b\z#+b\zvel#
		b\yvel = b\yvel - ball_gravity#
		TranslateEntity b\entity,b\xvel*dt,b\yvel*dt,b\zvel*dt
	Next
End Function


Function HandleBalls(b.ball,i)

	ent=CollisionEntity(b\entity,i)
	ctype=GetEntityType(ent)

	Nx# = CollisionNX#(b\entity, i) 
	Ny# = CollisionNY#(b\entity, i) 
	Nz# = CollisionNZ#(b\entity, i) 
	
	;If collision with ball
	If ctype=col_ball
		For b2.ball = Each ball
		 	If b2\entity=ent
			
;************************************************************************************************
;Hereīs the problem:
;Now jusing just same code as bouncing off walls.
;Problem: Balls sometimes seem to travel around each other instead of bouncing,
; trying to get momentum conservation into code always failed :(

				VdotN# = b\xvel#*Nx# + b\yvel#*Ny# + b\zvel#*Nz# 
				NFx# = -2.0 * Nx# * VdotN# 
				NFy# = -2.0 * Ny# * VdotN# 
				NFz# = -2.0 * Nz# * VdotN# 
				b\xvel#=(b\xvel# + NFx#)
				b\yvel#=(b\yvel# + NFy#)
				b\zvel#=(b\zvel# + NFz#)
;************************************************************************************************

				Exit
			EndIf
		Next
	Else
	;If Collision with wall
	VdotN# = b\xvel#*Nx# + b\yvel#*Ny# + b\zvel#*Nz# 
	NFx# = -2.0 * Nx# * VdotN# 
	NFy# = -2.0 * Ny# * VdotN# 
	NFz# = -2.0 * Nz# * VdotN# 
	b\xvel#=(b\xvel# + NFx#)
	b\yvel#=(b\yvel# + NFy#)
	b\zvel#=(b\zvel# + NFz#)

	;Slowdown:
	
	;b\xvel=b\xvel*.99
	;b\yvel=b\yvel*.99
	;b\zvel=b\zvel*.99

EndIf

End Function

Function UpdateGame ()
	 If KeyDown (203) TurnEntity cam, 0,2, 0 
 	If KeyDown (205) TurnEntity cam, 0,-2, 0 
	 If KeyDown (200) MoveEntity cam, 0, 0, 15
 	If KeyDown (208) MoveEntity cam, 0, 0, -15
 	If KeyHit (17): mode_wire = 1 - mode_wire: WireFrame mode_wire: EndIf 

	 ;mx#=MouseXSpeed()*0.5
	 ;my#=MouseYSpeed()*0.5
	 ;MoveMouse screen_width/2,screen_height/2
 	;TurnEntity cam,0,0,0




Any help would be really appreciated.

Cy


Gabriel(Posted 2004) [#2]
Not really my subject, but I recall that GFK was working on a snooker game. Last I heard he was considering open-sourcing it, so he may be able to help.


cywhale(Posted 2004) [#3]
Hmmm...
maybe i found a solution, just have to test for some time, seems to work until now.

Besides - fixed some errors in table setup / ball size ;) Everything was scaled twice the size it should be...


bradford6(Posted 2004) [#4]
easy answer: use TOKAMAK


cywhale(Posted 2004) [#5]
:)
Thanks
Good idea.
The problem is, iīd like to try to understand the physics and their programming - so using a ready-to-use engine would not help ;)


Jeremy Alessi(Posted 2004) [#6]
I had quite a few problems with smoothing out the ball and player physics in Aerial Antics. They used to be quite erratic but with some added code I was able to fix it up pretty nicely. If you add the conservation code at the proper place it should work fine. In my simulation I assumed the ball was massless in comparison to the player but I still had to throw in some code to make sure it picked up the players velocity etc.

I beleive a big problem was that collisions move the objects back which can mess with the velocity components in the above calculations. You actually need to stop the objects from moving and make sure they are not colliding otherwise the collision system will interfere with the velocity of and object since it automatically moves objects back to their last position before collision occured.

It's been about 8 months since I messed with that stuff. I'd be more specific but I don't have much time right now. I'll try to pull out the code later.


Apocalypse(Posted 2004) [#7]
I made a change to the UpdateBalls function to use MoveEntity instead of TranslateEntity. It looks like its working to me but then again it's late and I'm tired.

Function UpdateBalls(dt#=1)
For b.ball = Each ball
For i = 1 To CountCollisions(b\entity)
HandleBalls(b.ball,i)
Next
b\x#=b\x#+b\xvel#
b\y#=b\y#+b\yvel#
b\z#=b\z#+b\zvel#
b\yvel = b\yvel - ball_gravity#
;TranslateEntity b\entity,b\xvel*dt,b\yvel*dt,b\zvel*dt
MoveEntity b\entity,b\xvel*dt,b\yvel*dt,b\zvel*dt
Next
End Function


poopla(Posted 2004) [#8]
Couldnt you just use tokomak? :) I'm good with physics and even I say just use Tokomak lol.