How do you handle Momentum?

Blitz3D Forums/Blitz3D Programming/How do you handle Momentum?

The forum is locked. These are the original blitzbasic.com forums, kept so they can still be read. No new topics, replies or edits can be made here. To join in, head over to the Blitz3D+ forums.

OK - You may shoot me down in flames for this, but here's the program with which I've been testing.
Apologies for the sloppy code, but that wasn't the idea of this.

I would prefer that I'm doing something wrong here because if it's a bug, surely it could be quite significant.

Assuming I've not made a boo-boo, could someone please explain just how this collision table is supposed to work.

The circumstance with only a single collision recorded when one ball is stopped is reasonable. I feel that the other cases though need to be explained. - Cases 2 and 5

; Very unfinished - Test framework only
; Run with debug, when it stops, view debug log
; then kill program and repeat with different option
; Probably I'm doing something wrong but I can't find it
; Essentially all these variants are surely the same thing??

.Begin
Global v1#,v2#
Print "1 - Opposite Directions Similar Speed (2)"
Print "2 - Opposite Directions Differing Speeds (3)"
Print "3 - Ball1 Stopped (2)"
Print "4 - Ball2 Stopped (1)"
Print "5 - Same Directions (1)"
Print "6 - Both Stopped (Takes Quite a While)!"
Print
Print "Which Test 1-6"

.Here
If KeyDown(2) Then v1# = 0.3 : v2# = -0.3 : Goto Doit
If KeyDown(3) Then v1# = 1.5 : v2# = -0.02 : Goto Doit
If KeyDown(4) Then v1# = 0 : v2# = -0.3 : Goto Doit
If KeyDown(5) Then v1# = 0.3 : v2# = 0 : Goto Doit
If KeyDown(6) Then v1# = 0.3 : v2# = 0.05 : Goto Doit
If KeyDown(7) Then v1# = 0 : v2# = 0 : Goto Doit

Goto here

.Doit

Const Coll_Wall = 1
Const Coll_Ground = 2
Const Coll_Ball = 3

Const FPS=30
Global period=1000/FPS
Global time=MilliSecs()-period

Const ScrWid = 640
Const ScrHgt = 480

Global Camera1_Pivot,Camera1

Type ball
Field entity
Field index%
Field name$
Field mass#
Field xvel#,yvel#,zvel#
End Type


Global collcount
Dim collsubj$(20),collobj$(20),colltriangle#(20)

Dim coltab#(20)
Global colmod%

SetBuffer BackBuffer()
Graphics3D ScrWid,ScrHgt



Buildworld()

PositionEntity Camera1,0,15,-20
RotateEntity Camera1,30,0,0
RotateEntity Camera1_Pivot,0,0,0

Collisions Coll_Ball,Coll_Ball,1,1
; Main Loop
While Not KeyHit(1)

Repeat
elapsed=MilliSecs()-time
Until elapsed

ticks=elapsed/period
tween#=Float(elapsed Mod period)/Float(period)

For k=1 To ticks
time=time+period
If k=ticks Then CaptureWorld
UpdateBalls()
UpdateWorld
Next

RenderWorld tween

Flip
Wend

End

Function BuildWorld()
Cls
HidePointer
AmbientLight(255,255,255)

Camera1_Pivot = CreatePivot()
PositionEntity Camera1_Pivot,0,0,0
Camera1 = CreateCamera(Camera1_Pivot)

Board = CreateCube()
ScaleMesh Board,20,0.2,20
EntityColor Board,100,200,100
EntityType Board,Coll_Ball
EntityRadius board,2
PositionEntity Board,0,-0.2,0

b.ball = New ball ; Yellow Ball
b\index% = 1
b\name$ = "Yellow"
b\entity = CreateSphere()
EntityColor b\entity,255,255,20
EntityType b\entity,Coll_Ball
ScaleEntity b\entity,2,2,2
EntityRadius b\entity,2
PositionEntity b\entity,-10,10,10
b\mass# = 1
b\xvel# = v1#
b\yvel# = 0
b\zvel# = 0

b.ball = New ball ; Magenta Ball
b\index% = 2
b\name$ = "Magenta"
b\entity = CreateSphere()
EntityColor b\entity,255,0,255
EntityType b\entity,Coll_Ball
ScaleEntity b\entity,2,2,2
EntityRadius b\entity,2
PositionEntity b\entity,10,10,10
b\mass# = 1
b\xvel# = v2#
b\yvel# = 0
b\zvel# = 0

End Function


Function UpdateBalls(dt#=1);
DebugLog "UpdateBalls Begins"
collcount = 0
For b.ball = Each ball
c = CountCollisions(b\entity)
If c = 0 Then ; No collision
DebugLog "No collisions for ball "+b\name$
Else
For i = 1 To c ; For each collision for this ball
collcount% = collcount% + 1 ; Store Index of collision object
d$ = ""
d$ = d$ + b\name$ + "-"
collsubj$(collcount%) = b\name$
ent = CollisionEntity(b\entity,i)
For b2.ball = Each ball ; Find name of collision object
If ent = b2\entity Then
collobj$(collcount%) = b2\name$
d$ = d$ + b2\name$ + " "
Nx# = CollisionNX#(b\entity,i) ; Get Collision Suface Normals
Ny# = CollisionNY#(b\entity,i)
Nz# = CollisionNZ#(b\entity,i)
VdotN# = (b\xvel#*Nx#)+(b\yvel#*Ny#)+(b\zvel#*Nz#) ; Vector Product
NFx# = -2 * Nx# * VdotN# ; Normal Force (direction)
NFy# = -2 * Ny# * VdotN#
NFz# = -2 * Nz# * VdotN#
b\xvel# = b\xvel# + NFx#
b\yvel# = b\yvel# + NFy#
b\zvel# = b\zvel# + NFz#
EndIf
Next
DebugLog d$
Next
EndIf
Next


For b.ball = Each ball

TranslateEntity (b\entity,b\xvel#,b\yvel#,b\zvel#)
Next
ShowStats()
DebugLog "UpdateBalls Ends"
DebugLog ""
End Function


Function ShowStats()

If collcount > 0
Text 10,10,Str(collcount) + " Collisions Logged"
For j = 1 To collcount
Text 10,30+(j*15),collsubj$(j)+"-"+collobj$(j)+" "
Next
Flip
Stop
End If


End Function


My thanks go to anyone who cares to explain.