I am new to Blitz3D (about 6 days) but I found the forums lacking in pure Blitz source code examples for physics. There are alot of 3rd party examples like Tokamac etc but I prefer to exhaust purely coded solutions before moving to 3rd party code.
Here is a demo I made which simulates balls interacting on a plane (Basketballs perhaps) but the values can easily be changed to simulate pool balls or a squash court. I'd like to get some opinions from some more experienced Blitz coders as to my solution.
***********************************************
;
; 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 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
;******* Create Initial Ball ******
Blitz.Ball_Object = New Ball_Object
InitBallVars(Blitz)
Collisions BALLS, BALLS, 1, 2
;***** Create Camera *****
camera=CreateCamera()
PositionEntity camera,0,15,-55
;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(8)
ScaleEntity Ball\Entity, 1,1,1
txt=LoadTexture("Blitzlogo.bmp")
EntityTexture Ball\Entity, txt
EntityType Ball\Entity, BALLS
;*** 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#=.90 ;value from >0 to <1 (1=pure elastic collision)
Ball\friction#=.025
;**************************
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
AlignToVector Ball\Entity, Ball\dx, Ball\dy, Ball\dz,3
End If
If Ball\x >= Ball\xMax# Then
Ball\x = Ball\xMax#
Ball\dx = -Ball\dx
Ball\dx = Ball\dx * Ball\elasticity
AlignToVector Ball\Entity, Ball\dx, Ball\dy, Ball\dz,3
End If
If Ball\z =< Ball\zMin# Then
Ball\z = Ball\zMin#
Ball\dz = -Ball\dz
Ball\dz = Ball\dz * Ball\elasticity
AlignToVector Ball\Entity, Ball\dx, Ball\dy, Ball\dz,1
End If
If Ball\z >= Ball\zMax# Then
Ball\z = Ball\zMax#
Ball\dz = -Ball\dz
Ball\dz = Ball\dz * Ball\elasticity
AlignToVector Ball\Entity, Ball\dx, Ball\dy, Ball\dz,1
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
;Rotate mesh to give appearance of rolling
TurnEntity Ball\Entity, Ball\dz*50,0,0, 1
End Function
*********************************************
PS: You will need the file 'Blitzlogo.bmp' to run the demo.
Thanks
Here is a demo I made which simulates balls interacting on a plane (Basketballs perhaps) but the values can easily be changed to simulate pool balls or a squash court. I'd like to get some opinions from some more experienced Blitz coders as to my solution.
***********************************************
;
; 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 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
;******* Create Initial Ball ******
Blitz.Ball_Object = New Ball_Object
InitBallVars(Blitz)
Collisions BALLS, BALLS, 1, 2
;***** Create Camera *****
camera=CreateCamera()
PositionEntity camera,0,15,-55
;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(8)
ScaleEntity Ball\Entity, 1,1,1
txt=LoadTexture("Blitzlogo.bmp")
EntityTexture Ball\Entity, txt
EntityType Ball\Entity, BALLS
;*** 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#=.90 ;value from >0 to <1 (1=pure elastic collision)
Ball\friction#=.025
;**************************
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
AlignToVector Ball\Entity, Ball\dx, Ball\dy, Ball\dz,3
End If
If Ball\x >= Ball\xMax# Then
Ball\x = Ball\xMax#
Ball\dx = -Ball\dx
Ball\dx = Ball\dx * Ball\elasticity
AlignToVector Ball\Entity, Ball\dx, Ball\dy, Ball\dz,3
End If
If Ball\z =< Ball\zMin# Then
Ball\z = Ball\zMin#
Ball\dz = -Ball\dz
Ball\dz = Ball\dz * Ball\elasticity
AlignToVector Ball\Entity, Ball\dx, Ball\dy, Ball\dz,1
End If
If Ball\z >= Ball\zMax# Then
Ball\z = Ball\zMax#
Ball\dz = -Ball\dz
Ball\dz = Ball\dz * Ball\elasticity
AlignToVector Ball\Entity, Ball\dx, Ball\dy, Ball\dz,1
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
;Rotate mesh to give appearance of rolling
TurnEntity Ball\Entity, Ball\dz*50,0,0, 1
End Function
*********************************************
PS: You will need the file 'Blitzlogo.bmp' to run the demo.
Thanks