How do you handle Momentum?
Blitz3D Forums/Blitz3D Programming/How do you handle Momentum?
| ||
I know that there is a lot of information on collisions in these forums, but I can't seem to find anything which addresses my particular query. I hope that some of you out there will be able to help. From what I've read, and have found by experimenting, for any collision between two spheres, the contents of the collision table indexed by CountCollisions(entity) seems to vary depending upon the circumstances of the collision. i.e whether both objects are travelling in opposing directions, both in the same direction but at differing speeds, or if either is stopped. Sometimes there seem to be multiple entries for the same entity, I guess if there have been multiple collisions within a single UpdateWorld. It appears that once a collision has happened, there may be one, two or even more entries in the collision table for the same event. I know that if these were collisions with infinite mass objects, this would probably not matter since the rebounds of each can be calculated from the collision normals for each, but if one is trying to handle the momentum properly, collecting all entries which relate to the same event seems to be tricky, to say the least. Am I understanding things properly, and is there an 'approved' method of linking up these entries, or am I missing something and in reality its all extremely easy? |
| ||
Check the code archives http://www.blitzbasic.com/codearcs/codearcs.php?code=751 |
| ||
Many thanks for that speedy reply. I missed that example in the code archives and it is certainly very interesting. Whilst it does thoroughly answer part of my query, it doesn't in any way answer the query as to how the collision table is populated by Blitz3D. From further experimentation, you seem to get one entry if two spheres collide whilst one is stopped, two entries if they are both moving at similar velocities, and three entries if their speeds vary considerably. (And not surprisingly, no entries if they are both stopped!!) I think I'm comfortable as to why that should be, but would like to feel that my findings can be relied upon. Also, are there circumstances when the same two spheres can cause 4 or more entries in the collision table? The example to which you referred completely avoids the normal collision mechanism, and whilst its a fascinating way to do things, I shudder to think how it could be developed into a general solution in a more complicated 3D world. Can anyone point me to an article which fully explains the collision table? |
| ||
Paul: I've been using Blitz3D for a long time, and I've never heard of more than one collision being reported when two objects collide. I doubt that you will find any information on that. I also don't reccomend that you assume that more than one collision will be reported when two objects are moving at certain speeds. It seems very likely that that would change in the future, as only a single collision should be reported in a properly functioning collision system that functions as Blitz's does. I do know that Blitz's collision system doesn't handle most collisions between moving objects correctly and that Mark has mentioned that it needs to be fixed. Mark designed the system so that objects that collide will not interpenetrate, but when more than one object is moving and they collide, they do interpentrate, and that's an issue that needs to be corrected. The fact that the two objects are interpenetrating is likely what leads to the erroneous reporting of multiple collisions. I thought the one exception to the moving object interpenetration issue was between moving spheres, and that collisions between these could be relied upon. However, if what you say is true, then that is clearly not the case. I suppose it's possible Mark broke moving sphere collisions when he implemented ellipsoid collisions. Some folks were complaining in the bug reports forum about ellipsoid collisions not working as expected. I think some other folks also complained about regular sphere collisions being broken in some way as a result as well. |
| ||
In my latest project I've noticed that with basic sphere-polygon collision the sphere sometimes drops through the mesh. I can't seem to find any rhyme or reason why this happens but it does... bloody annoying... trying to find a way round it. |
| ||
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 "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. |
| ||
Would that mesh happen to be a terrain? Terrains change their meshes dynamically as you move around. A polygon which had a sharp indentation a moment ago beneath the sphere, may suddenly get smoothed over as more detail is added, resulting in the sphere interpenetrating the mesh. Interpenetration breaks the collision system. Of course I'm just guessing that Mark didn't code some workaround to this issue into his terrain system. |
| ||
I realise now that I probably asked the wrong question at the start of this thread! Can anyone please tell me if this is a bug or am I just not unerstanding. Thanks. |
| ||
I'm pretty sure it's a bug. If you want to do collisions between two moving spheres, you may have to write your own sphere to sphere collision routine. |