Code archives/3D Graphics - Maths/Ball rolling example

This code has been declared by its author to be Public Domain code.

Download source code

Ball rolling example by Jeppe Nielsen2003
Shows how you can make a ball roll
;Ball rolling physics example by Jeppe Nielsen 2003

Const gravity#=-0.04;-0.02 ;gravity constant

Graphics3D 800,600,16,1

Const ball_col=1
Const world_col=2

Collisions ball_col,world_col,2,2

Global texture

texture=CreateTexture(16,16)

SetBuffer TextureBuffer(texture)

Color 255,255,255
Rect 0,0,16,16,1

Color 255,0,0
Rect 0,0,8,8,1
Rect 8,8,8,8,1

ScaleTexture texture,0.1,0.1


Global groundtexture=CreateTexture(32,32,1+8)

SetBuffer TextureBuffer(groundtexture)

Color 0,0,0
Rect 0,0,32,32,1

Color 0,0,255
Rect 0,0,32,32,0

ScaleTexture groundtexture,2,2

SetBuffer BackBuffer()
Color 255,255,255

plane=CreatePlane()
EntityTexture plane,groundtexture
EntityType plane,world_col
EntityAlpha plane,0.5

mirror=CreateMirror()




light=CreateLight(1)
RotateEntity light,30,20,0


obj=CreateCube()

EntityType obj,world_col
PositionEntity obj,0,0,0
ScaleEntity obj,10,10,10
RotateEntity obj,45,0,0



camera=CreateCamera()
CameraClsColor camera,0,0,255


ball.ball=ballnew(0,4,-120,2,0.8)


zoom#=14

Repeat

zoom#=zoom#-MouseZSpeed()
ballcamera(camera,ball,0,zoom#,-zoom#,0,5,0)


ballcontrol()
ballupdate()

RenderWorld()

Text 10,10,"Arrow keys to control ball"
Text 10,30,"Scroll on mouse to zoom"


Flip


Until KeyDown(1)
End


Type ball

Field e ;entity

Field sphere

Field pivot

Field x#,y#,z# ; position in 3d-space

Field vx#,vy#,vz# ; velocity

Field ax#,ay#,az# ; acceleration

Field size#

Field bounce# ; bounce factor

Field vel#

Field vx2#,vy2#,vz2# ; temp velocity

End Type


Function ballnew.ball(x#,y#,z#,size#=1,bounce#=0.9)
	
	c.ball=New ball
	
	c\x#=x#
	c\y#=y#
	c\z#=z#
	
	c\size=size
	
	c\bounce#=bounce#
	
	c\e=CreatePivot()
		
	c\sphere=CreateSphere(64)
	
	c\pivot=CreatePivot()
	
	EntityType c\e,ball_col
	EntityRadius c\e,c\size
	
	PositionEntity c\e,c\x,c\y,c\z
	ScaleEntity c\sphere,c\size,c\size,c\size
	
	EntityTexture c\sphere,texture
	
	Return c
	
End Function

Function ballupdate()
	
	For c.ball=Each ball
	
			
		c\vy#=c\vy#+gravity#
		
		c\vx#=c\vx#+c\ax#
		c\vy#=c\vy#+c\ay#
		c\vz#=c\vz#+c\az#
		
		c\x#=EntityX(c\e)
		c\y#=EntityY(c\e)
		c\z#=EntityZ(c\e)
		
		TranslateEntity c\e,c\vx,c\vy,c\vz	
	
	Next
	
	UpdateWorld()
		
	For c.ball=Each ball
	
		;correct velocity if collided
		c\vx2=(EntityX(c\e)-c\x)
		c\vy2=(EntityY(c\e)-c\y)
		c\vz2=(EntityZ(c\e)-c\z)
		
		c\x#=EntityX(c\e)
		c\y#=EntityY(c\e)
		c\z#=EntityZ(c\e)
		
		PositionEntity c\sphere,c\x,c\y,c\z
		PositionEntity c\pivot,c\x,c\y,c\z
		
		If EntityCollided(c\e,world_col)
				
			For i = 1 To CountCollisions(c\e)
				; Get the normal of the surface which the entity collided with. 
				Nx# = CollisionNX(c\e, i) 
				Ny# = CollisionNY(c\e, i) 
				Nz# = CollisionNZ(c\e, i) 
				
				; Compute the dot product of the entity's motion vector and the normal of the surface collided with. 
				VdotN# = c\vx#*Nx# + c\vy#*Ny# + c\vz#*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\vx# = c\vx# + NFx# * c\bounce#
				c\vy# = c\vy# + NFy# * c\bounce#
				c\vz# = c\vz# + NFz# * c\bounce#

				avx#=EntityPitch(c\sphere)
				avy#=EntityYaw(c\sphere)
				avz#=EntityRoll(c\sphere)

				;Rotate stuff
				;Get vector from center to collision
				dx1#=(CollisionX(c\e,i)-c\x)
				dy1#=(CollisionY(c\e,i)-c\y)
				dz1#=(CollisionZ(c\e,i)-c\z)
				
				dx2#=c\vx
				dy2#=c\vy
				dz2#=c\vz
				
				;Cross product
				cx# = ( dy1 * dz2 ) - ( dz1 * dy2 ) 
				cy# = ( dz1 * dx2 ) - ( dx1 * dz2 ) 
				cz# = ( dx1 * dy2 ) - ( dy1 * dx2 ) 				
															
				AlignToVector c\pivot,cx,cy,cz,1
																									
			Next
			
			Nx# = CollisionNX(c\e, 1) 
			Ny# = CollisionNY(c\e, 1) 
			Nz# = CollisionNZ(c\e, 1) 				
					
			AlignToVector c\e,Nx#,Ny#,Nz#,2,0.5
			
			c\vel#=Sqr(c\vx2*c\vx2+c\vy2*c\vy2+c\vz2*c\vz2)
						
			;slow down due to friction
			c\vx#=c\vx*0.98
			c\vy#=c\vy*0.98
			c\vz#=c\vz*0.98
					

		EndIf

			
		EntityParent c\sphere,c\pivot
								
		TurnEntity c\pivot,-c\vel#*(180/Pi)/c\size#,0,0

		EntityParent c\sphere,0

		c\ax#=0
		c\ay#=0
		c\az#=0	
		
	Next
	
End Function


Function ballcontrol()
	
	For c.ball=Each ball
		
		If KeyDown(200)
			
			TFormVector 0,0,0.03,c\e,0
			
			c\ax#=TFormedX()
			c\ay#=TFormedY()
			c\az#=TFormedZ()
			
		EndIf
		
		If KeyDown(208)
			
			c\vx=c\vx*0.94
			c\vy=c\vy*0.94
			c\vz=c\vz*0.94
			
		EndIf
		
		If KeyDown(57)
			
			TFormVector 0,0.05,0,c\e,0
			
			c\ax#=c\ax+TFormedX()
			c\ay#=c\ay+TFormedY()
			c\az#=c\az+TFormedZ()
			
									
		EndIf
		
		If KeyDown(203)
			
			TurnEntity c\e,0,2,0
			
		EndIf
		
		If KeyDown(205)
			
			TurnEntity c\e,0,-2,0
			
		EndIf
		
		
	Next
	
	
	
End Function

Function ballcamera(camera,b.ball,camx#,camy#,camz#,aimx#=0,aimy#=0,aimz#=0,smoothcam#=0.1,roll#=0)
	
	TFormPoint camx#,camy#,camz#,b\e,0
	
	dx#=(TFormedX()-EntityX(camera))*smoothcam#
	dy#=(TFormedY()-EntityY(camera))*smoothcam#
	dz#=(TFormedZ()-EntityZ(camera))*smoothcam#
	
	TranslateEntity camera,dx,dy,dz
	
	TFormPoint aimx#,aimy#,aimz#,b\e,0
	
	dx# = EntityX(camera)-TFormedX()
	dy# = EntityY(camera)-TFormedY()
	dz# = EntityZ(camera)-TFormedZ()
	dist#=Sqr#((dx#*dx#)+(dz#*dz#))
	pitch#=ATan2(dy#,dist#)
	yaw#=ATan2(dx#,-dz#)
	
	RotateEntity camera,pitch#,yaw#,roll#
	
End Function

Comments

Q2006
My current project involves controlling a ball, this has pointed me in the right direction. Thanks! :o)


Jeepster2006
cool. I just have one question:
what part(s) of the code make an object solid? when I try to add another cube, the ball rolls right through it!


Jeepster2006
wait, never mind, I got it
anyway, good show. I also have a project that involves controlling a ball


puki2006
This is great.


Curtastic2006
This is awesome. I thought the ball was jerking but it was just the camera. For now something like this can be used to make it smooth.
Function ballcamera(camera,b.ball,camx#,camy#,camz#,aimx#=0,aimy#=0,aimz#=0,smoothcam#=0.1,roll#=0)
	TFormPoint camx#,camy#,camz#,b\e,0
	
	dx#=(TFormedX()-EntityX(camera))*smoothcam#
	dz#=(TFormedZ()-EntityZ(camera))*smoothcam#
	
	TranslateEntity camera,dx,0,dz
	PositionEntity camera,EntityX(camera),EntityY(b\e)+15,EntityZ(camera)
	PointEntity camera,b\e
End Function



Rook Zimbabwe2006
This is cool also! OK Jieppe Gets my vote for BLitzgy of the year!!!


Captain Wicker (crazy hillbilly)2012
This code may be almost a decade old, but it still rocks!


GaryV2012
R.I.P. Rook Zimbabwe :(


Code Archives Forum