Proper Ball Aiming

Blitz3D Forums/Blitz3D Programming/Proper Ball Aiming

Apocalypse(Posted 2004) [#1]
Thanks to everybody who helped me perfect this algorithm.
Now we have collision with convervation of momentum as
well as accurate rolling simulation. Here is the code if
anybody wants to use it. Feel free....

;
; Bouncing ball physics - by Vincent DeCampo 2/1/04
;

Const GRAVITY#=-.05
Const BALLS=1

Graphics3D 640,480

;*** Type for Ball ***
Type Ball_Object
	Field Entity
	Field Pivot
	Field x#
	Field y#
	Field z#
	Field dx#
	Field dy#
	Field dz#
	Field xMin#
	Field xMax#
	Field yMin#
	Field yMax#
	Field zMin#
	Field zMax#
	Field elasticity#
	Field friction#
End Type

;*** Lets create the floor ***
Room=CreateTerrain(64)
PositionEntity room,-32,0,-32
EntityColor Room, 0, 150, 0

;******* Create Initial Ball ******
Blitz.Ball_Object = New Ball_Object
InitBallVars(Blitz)
Collisions BALLS, BALLS, 1, 2

;***** Create Camera *****
camera=CreateCamera()
PositionEntity camera,0,5,-40
PointEntity camera, Blitz\Entity

;**********************************
;			 Main Loop
;**********************************
;
While Not KeyHit(1)

	If KeyHit(57) Then

		;***** Seed RND Generator *****
		SeedRnd (MilliSecs())
		
		;*** Create New Ball ***
		Blitz.Ball_Object = New Ball_Object	
		InitBallVars Blitz

	End If

	;**** Perform Room Physics ****
	For Ball.Ball_Object = Each Ball_Object
		BallPhysics (Ball)		
	Next

	UpdateWorld	

	;**** Perform Ball-on-Ball Physics ****
	CheckCollisions (Blitz)
		
	RenderWorld 

	Text 0,5,"Press SPACE to throw another ball"
	Text 0,15,"Press ESC to Exit"

	Flip

Wend

End

;**********************************

Function CheckCollisions (Ball.Ball_Object)

	For C.Ball_Object = Each Ball_Object
				
		If EntityCollided(c\Entity, BALLS)
					
			For i = 1 To CountCollisions(c\Entity)

				Ent=CollisionEntity (c\Entity, i)

				;Get the normal of the surface which the entity collided with. 
				Nx# = CollisionNX(c\Entity, i) 
				Ny# = CollisionNY(c\Entity, i) 
				Nz# = CollisionNZ(c\Entity, i) 
			
				;Compute the dot product of the entity's motion vector And the normal of the surface collided with. 				
				VdotN# = (c\dx# * Nx# + c\dy# * Ny# + c\dz# * Nz#)
									
				;Calculate the normal force. 
				NFx# = -2.0 * Nx# * VdotN# 
				NFy# = -2.0 * Ny# * VdotN# 
				NFz# = -2.0 * Nz# * VdotN# 
										
				;Add the normal force to the direction vector. 
				c\dx# = c\dx# + NFx#/2
				c\dy# = c\dy# + NFy#/2	;Force /2 assumes balls equal in mass
				c\dz# = c\dz# + NFz#/2
								
				For Hit.Ball_Object = Each Ball_Object

					If Hit\Entity = Ent Then
						
						;Add negative force to collision entity vector		
						Hit\dx# = Hit\dx# - NFx#/2
						Hit\dy# = Hit\dy# - NFy#/2	;Force /2 assumes balls equal in mass
						Hit\dz# = Hit\dz# - NFz#/2		
											
					End If
																									
				Next

			Next
												
		EndIf
		
	Next
							
End Function

;**********************************

Function InitBallVars(Ball.Ball_Object)

	;Create Ball
	Ball\Entity=CreateSphere()
	ScaleEntity Ball\Entity, 1,1,1
	EntityType Ball\Entity, BALLS

	txt=LoadTexture("blitzlogo.bmp")
	EntityTexture Ball\Entity, txt
	
	;Create Pivot
	Ball\Pivot=CreatePivot()
	
	;*** Variables for Ball ***	
	Ball\x#=0
	Ball\y#=20	;set ball 20 units above floor
	Ball\z#=0
	Ball\dx#=Rand(5)
	Ball\dy#=0	;at rest
	Ball\dz#=Rand(5)
	Ball\yMin#=1
	Ball\yMax#=9999
	Ball\xMin#=-32
	Ball\xMax#=32
	Ball\zMin#=-32
	Ball\zMax#=32
	Ball\elasticity#=.75	;value from >0 to <1 (1=pure elastic collision)
	Ball\friction#=.01
	;**************************

End Function

;**********************************

Function BallPhysics (Ball.Ball_Object)

	If ball\y   =< Ball\yMin# Then
		Ball\y  =  Ball\yMin#
		Ball\dy = -Ball\dy
		Ball\dy =  Ball\dy * Ball\elasticity
	End If

	If Ball\x   =< Ball\xMin# Then
		Ball\x  =  Ball\xMin#
		Ball\dx = -Ball\dx
		Ball\dx =  Ball\dx * Ball\elasticity
		UpdatePivot (Ball)
	End If

	If  Ball\x >=  Ball\xMax# Then
		Ball\x  =  Ball\xMax#
		Ball\dx = -Ball\dx
		Ball\dx =  Ball\dx * Ball\elasticity
		UpdatePivot (Ball)
	End If
	
	If Ball\z   =< Ball\zMin# Then
		Ball\z  =  Ball\zMin#
		Ball\dz = -Ball\dz
		Ball\dz =  Ball\dz * Ball\elasticity
		UpdatePivot (Ball)
	End If

	If Ball\z  >=  Ball\zMax# Then
		Ball\z  =  Ball\zMax#
		Ball\dz = -Ball\dz
		Ball\dz =  Ball\dz * Ball\elasticity
		UpdatePivot (Ball)
	End If
	
	If Ball\y  >= Ball\yMin# Then
		Ball\dy = Ball\dy + GRAVITY
	End If	

	Ball\x = Ball\x + Ball\dx
	Ball\z = Ball\z + Ball\dz
	Ball\y  = Ball\y + Ball\dy

	Ball\dx = Ball\dx - (Ball\dx*Ball\friction)
	Ball\dz = Ball\dz - (Ball\dz*Ball\friction)

	;Move ball to new coords
	PositionEntity  Ball\Entity, Ball\x, Ball\y, Ball\z, 0

	;Rotate mesh to give appearance of rolling	
	TurnEntity Ball\Entity, Ball\dz*50,0,-Ball\Dx*50, 1
			
End Function

Function UpdatePivot (Ball.Ball_Object)

	;Move pivot to coords + deltas
	PositionEntity Ball\Pivot, Ball\x+Ball\dx, Ball\y+Ball\dy, Ball\z+Ball\dz
	
	PointEntity Ball\Entity, Ball\Pivot, 0		

End Function



PS: You will need the file Blitzlogo.bmp as the ball texture.


wedoe(Posted 2004) [#2]
You can use the code-prefix to get your code
stand out better if you like.

You use [/code] after and [code] before the source.


Bot Builder(Posted 2004) [#3]
but then - for whatever reasons their are spaces between all the lines :(


Wayne(Posted 2004) [#4]
Nice


wedoe(Posted 2004) [#5]
but then - for whatever reasons their are spaces between all the lines :(
If you use Opera that is true, if you use MSIE the extra lines are added in both cases.

I usually paste in a text-doc always open on my desktop,
(to prevent cat paws stepping on the keyboard messing up things)
then copy it again from there to the BB IDE.


BlackJumper(Posted 2004) [#6]
Ctrl+V causes Blitz to paste in as a 'rich text' version from IE, but using the menu (Edit --> Paste) puts in a plain text version that uses the default font.