Help with Gravity/Bounce Code...
Blitz3D Forums/Blitz3D Programming/Help with Gravity/Bounce Code...
| ||
I whipped up this little demo to show basic gravity and a ball bouncing. The problem is that it's buggy as heck. Sometimes it bounces super high. Other times it bounces twice and stops. See anything wrong? btw: if you want to run it you need the vector.bb lib from the archives ;// Gravity and Bounce Example Graphics3D 800,600,16 SetBuffer BackBuffer() Include "vector.bb" ;// Set Gravity meters per sec g# = -9.8 ;// Ball Parameters ball = CreateSphere() ScaleEntity ball,0.5,0.5,0.5 mass = 10 ;// Set Initial Forces and Vectors vFor.vector = vector() ;force vector vAcc.vector = vector() ;acceleration vector vVel.vector = vector() ;velocity vector vPos.vector = vector(0,20,0) ;position vector ;// Timing NewTime% = MilliSecs() OldTime% = NewTime ;// Camera and Lights camera = CreateCamera() PositionEntity camera,0,0,-20 light = CreateLight() ;// Main Loop While Not KeyHit(1) Cls ;// Find Delta Time NewTime = MilliSecs() delta# = Float (NewTime - OldTime) / 1000 OldTime = NewTime FPS = 1 / delta ;// Reset Forces to Zero Each Cycle Vector_Reset vFor ;// Calculate Gravity vFor\y = g * mass ;// Collision If vPos\y < 0 Then Collided = True If Collided = True speed# = Vector_Magnitude(vVel) collided = False vFor\y = -vFor\y * (Float (speed / 2)) * mass vVel\y = 0 EndIf ;// Up Arrow Key applies 100 force upwards If KeyDown(200) Then vFor\y = 100 ;// Calc New Acc, Vel, and Pos Vector_DivideScalar vAcc,vFor,mass Vector_AddTimeStep vVel,vAcc,delta Vector_AddTimeStep vPos,vVel,delta ;// Position the Ball Vector_PositionEntity ball,vPos UpdateWorld RenderWorld ;// Show What's Happening Text 5,5,"FPS=" + FPS Text 5,50,"Speed=" + Int(Vector_Magnitude(vVel)) Vector_Show(vFor,5,100,"Force") Vector_Show(vAcc,5,175,"Acc") Vector_Show(vVel,5,250,"Vel") Vector_Show(vPos,5,325,"Pos") Flip Wend End |
| ||
No problems yet and I ran it about 12 times... same results every time... {{EDIT}}OK after I post that I see what you mean... it starts going wonky... It looks like the velocity is being ADDED to rather than being subtracted in a constant ratio... I changed the drop height to 15 (added a mirror plane as well for fun) and it sometimes adds and adds... it is probably something in the vector.bb... let me look... Oh my code: |
| ||
I made a small change to the vector.bb it is slightly more accurate and realistic change the funtion thus:Function Vector_Magnitude#(v.Vector) Return Sqr((v\x * v\x) + (v\y * v\y) + (v\z * v\z)) / 2 End Functionand run it now!!! Then I did this to see: MASS seems to be a part of the problem... monkey with that and see... For some reason velocity adds at some point(possibly because of mass be applied wrongly I am uncertain!)... which is why I squelched magnitude a bit... RZ |
| ||
Change Flip to Flip False The ball drops like a stone. This may give you the idea what's wrong ... delta calculation could be wrong was my first thought when I looked at the code |
| ||
but it is weird that the bouncing would reduce normally and then spike to a positive 40 to 60 + up a bounce... BUT since MASS and GRAVITY effect DeltaV in his program it could just be something so simple... Hmmm RZ |
| ||
You consider the ball has collided if the y-position is below 0 right? Now, what will happen if the ball is still below 0 in the next frame? When you detect the collision, try positioning the ball at 0 or a little bit above, like 0.001 or something, and see if that helps. [Edit] To "visualize" the problem, add a CollisionCount variable that you increase by one at every collision and print it on screen. |
| ||
Yep it was registering multiple collisions on a single bounce. Setting the vPos\y to 0 after a successful collision fixed it. |
| ||
See... it was something very simple... Good catch Sweenie! |
| ||
Well it works for a simple bouncing off a floor (actualy a limiting value). Now make it so you can have 2 balls bounce off each other with the right trajectory. Not simple. |
| ||
Doing a pool type game? There MIGHT be some sample code... RZ |
| ||
It is pretty simple really ... I'm sure darkeagle / swift and others have examples in the archives or over at bcoder. In fact here's one .. http://www.blitzbasic.com/codearcs/codearcs.php?code=670 |
| ||
You might have read this already but I post it anyway. It's a great tutorial on the topic. http://www.gamasutra.com/features/20020118/vandenhuevel_01.htm |
| ||
This demo - not by me, BTW - may be of some use? [edit] Actually, I've just seen some 'sticky' collisions happening when 2 balls hit, so there must be a bugette somewhere. Like I said, not my code so I ain't fixing it. :) |
| ||
I think if you translate the 2 balls involved in the collisions by a small fraction of the collision normals then the stickyness will be eliminated. |
| ||
a) Move the balls apart along the collisionnormal until they are separated(as Stevie says) and apply the collisionresponse or b) Only allow collisionsresponse to happen when the balls are intersecting and moving towards each other(non separating) and ignore the collisionresponse if they are moving away from each other(separating) |