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....
PS: You will need the file Blitzlogo.bmp as the ball texture.
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.