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.
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 "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.