Collision Problem

Please don't post Bullet support questions here, use the above forums instead.
lowv
Posts: 5
Joined: Fri Jan 18, 2008 1:41 am

Collision Problem

Post by lowv »

Hi,
I'm glad to have found this forum. The thing is that I'm currently working on a small simulation mainly instructed by Chris Hecker's articles. I've figured out the collision detection through line intersections which are reconstructed to edges and vertices and this part seems to work fine, at least to my standards. Now the problem is that my collision response part behaves in quite a strange way, that is the angular component seems to be resolved nicely while there is practically no change in linear momentum, i.e. bodies which don't collide spinning and near their vertices just interpenetrate with minimal deflection. So as a last resort and after much tinkering around I decided to eliminate the angular portion of the impulse equation. I'm not sure about how it's supposed to look, but now it seemed as if the linear part was working acceptably as long as the body was NOT spinning or just rotating lightly, else the impulse went through the roof. It's coded in Blitzmax. Here's the Collision Resolve function: + I had to upload the program to megaupload as it was too big to attach: http://www.2shared.com/file/2747637/78e ... ation.html
Left Mouse -> Pull; Right -> Hold and Move

Code: Select all

Function ResolveBodyCollision(A:Body, B:Body, PerpA:Vector, PerpB:Vector, VAB:Vector, Unit:Vector)   
                                                                                                     
  Local e# = 0.6
  Local n1#, n2#
  Local dot1#, dot2#
  Local dn1#, dn2#, dn3#, dn4#

  Local n#
  Local dn#

  Local imp#
  Local I:Vector = New Vector 


  n1 = -1*(1+e)
  n2 = Vector.Dot(VAB, Unit)

  dot1 = Vector.Dot(PerpA, Unit)
  dot2 = Vector.Dot(PerpB, Unit)

  dn1 = Vector.Dot(Unit, Unit)
  dn2 = (A.mass + B.mass)/(A.mass*B.mass)
  dn3 = (dot1^2))/A.moi
  dn4 = (dot2^2))/B.moi

  n = n1*n2
  dn = dn1*dn2 + dn3 + dn4
  
  imp = n/dn
  I = Vector.Scale(Unit, imp)
  
  A.Vel = Vector.Add(A.Vel, Vector.Scale(I, (1/A.mass)))
  B.Vel = Vector.Sub(B.Vel, Vector.Scale(I, (1/B.mass)))

  A.angvel = A.angvel + (Vector.Dot(PerpA, I))/A.moi 
  B.angvel = B.angvel - (Vector.Dot(PerpB, I))/B.moi
End Function

Lowv
Last edited by lowv on Mon Jan 21, 2008 5:39 pm, edited 2 times in total.
lowv
Posts: 5
Joined: Fri Jan 18, 2008 1:41 am

Re: Collision Problem

Post by lowv »

Update:
Now the "linear impulse only" case is working correctly. I just forgot to eliminate the angular terms from the relative velocity calculation. Though I'm still not able to implement the general form of the impulse equation. I'm sure that my mistake lies either in the above function or even more likely the following part, which calculates the parameters needed for the function:

Code: Select all

  PBt = Vector.Add(Self.Pos, Self.VertArr[vtx])   '''' Self.VertArr[vtx] = radius vector of first body(=the one with vertex)
  PBtt = Vector.Sub(PBt, Pass.Pos)                  ''''calculates radius vector of second body (in local coordinates)

  PA = Vector.NormalLeft(Self.VertArr[vtx])      ''''constructs perpendicular radius v. of first colliding body
  PB = Vector.NormalLeft(PBtt)                       '''''constructs  "         "        "     " of second body


  U = Vector.NormalLeft(Pass.LineArr[ln])        ''''' constructs normal to edge of second body
  U.Normalize()
      

  VAt = Vector.Scale(PA, Self.angvel)          """ calculates total velocities in point A and B
  VBt = Vector.Scale(PB, Pass.angvel) 

  VA = Vector.Add(Self.Vel, VAt)
  VB = Vector.Add(Pass.Vel, VBt)             

  VAB = Vector.Sub(VA, VB)
  vabn = Vector.Dot(VAB, U)               ''''''''calculates relative normal velocity 
Do I maybe have to manipulate the velocites in some way before substracting them? Aren't they already in global coordinates or am I wrong. Sorry if I sound annoying, but this whole program is part of my school research paper and I'm obviously no expert at physics or programming.
I'd be very happy if someone could point out the problem.
lowv
bone
Posts: 231
Joined: Tue Feb 20, 2007 4:56 pm

Re: Collision Problem

Post by bone »

I'm not getting very far in the code ... starting with your second post and code snippet there ...

First things first ... this is in 2-D, correct? Sorry I didn't download and look at the program. I am assuming it's 2-D because you are able to come up with a perpendicular vector using only one other vector.

"Self" is the first body, correct? Then I assume "Pass" is the second body. I don't mean to lecture, but this is where useful variables names would help (what does "Pass" mean? Passenger? How about "self" & "other" or maybe "body1" & "body2"?). I am assuming Self.Pos and Pass.Pos are the positions of each body in world coordinates. Is "Self.VertArr[vtx]" a local or world offset?

If it's a local offset, adding it to a world position doesn't make much sense. If it's a world offset, then PBt is the location of the impact in world coordinates. And that would then mean PBtt is the radius vector relative to the second body, but it's a world offset, not a local offset as the comment indicates.
lowv
Posts: 5
Joined: Fri Jan 18, 2008 1:41 am

Re: Collision Problem

Post by lowv »

Self is a command that refers to the same type (I think it's called a class in c++), so Pass refers to a body that was passed to it, which I've defined as the edge-colliding body in a vertex-edge situation. And yes, it's 2D. VertArr[] stores the bodies vertices as vectors in an array (relative to the center of mass). VertArr[vtx] is the "colliding vertex" = radius vector of body 1, PBtt = radius vector of body 2.
There shouldn't be much to go wrong if you consider that the equation works for me when I eliminate all angular terms in the denominator. Basically, something has to be wrong with the expression below that I've encircled red:
Image
Maybe you should take a look at the program. Notice that if the collision is directly central, i.e. you turn one rectangle 45°(using left mouse button), grab it (right mouse) and manage to hit the other one right in the middle of it's edge, then they bounce off like they should. In this case the perp. radius vectors of both bodies are exactly at right angle to the collision normal and the red terms in the equation become zero, as it should be. Now the problem obvously is that these two fractions become too big for any other scenario, so the calculated impulse is so small that a change in linear velocity is barely noticeable. I thought that it's the way I calculate the dot product, but then again to square means to square or am I missing something here? I say that because all values plugged into Hecker's equation seem to be plausible and right (I've drawn and printed them to see if they make sense)
but out comes some crap. I'm really getting desperate with this thing. I hope you understand my English.

Regards,
lowv
bone
Posts: 231
Joined: Tue Feb 20, 2007 4:56 pm

Re: Collision Problem

Post by bone »

OK, I'm understanding a lot more. So I assume VertArr[] is always being updated with the transformed (local-to-world) coordinates, correct? Then I still maintain the comment is incorrect regarding PBtt; it's the radius vector in world (global) coordinates.

Regardless, I can now follow the code. Can you define NormalLeft() for us? Does it simply switch the two coordinates, negating one of them? In other words, it's doesn't actually normalize the vector, correct?

Finally, perhaps a clue is in your statement that the denominator gets really big with any angular component. Perhaps your "moi" (moment-of-inertia) values are too small. Could you give us the mass, moi, and approximate size and shape of your objects to do a little reality check?
lowv
Posts: 5
Joined: Fri Jan 18, 2008 1:41 am

Re: Collision Problem

Post by lowv »

This quick sketch should clear things up:
Image
I think we're talking past each other regarding local/global but from the sketch you should be able to see what I mean.
You're right, VertArr[] gets updated for each body. NormalLeft() simply turns the vector by 90° to the left, i.e.
x = y
y = -x
Currently I have two rectangles with a Halfwidth of 50 to 50 pixels (thus 100 long to 100 wide) and a equilateral triangle (Sidelength: 150). All of them weigh 100 units and have a moment of inertia of 100.
But is that of any importance here, I mean if the equation was set up correctly then it would scale with these parameters ,wouldn't it?
bone
Posts: 231
Joined: Tue Feb 20, 2007 4:56 pm

Re: Collision Problem

Post by bone »

But is that of any importance here, I mean if the equation was set up correctly then it would scale with these parameters ,wouldn't it?

The equation would still be working correctly, but if the moi was too small it could end up spinning the object too fast. moi goes up with the square of the size (the SI unit for moi is kg * m^2); that's what tends to make big objects lumber around slowly, while tiny objects jitter around quickly (like rolling dice).

But after downloading and trying your program, I don't think that's the problem anyway.

Instead, I think there's some sort of sign problem somewhere. Perhaps the angvel should actually be turning the object in the opposite direction. Here's why I say that:

1) When I pull the object from the side, it linearly moves the correct way but it spins the wrong way.
2) In most of the collisions I saw, it also seemed to spin the objects in the opposite direction to what I expected.

There also seems to be some issue with collision detection, as the objects don't always show the red collision debugging info.

HTH
Last edited by bone on Tue Jan 22, 2008 4:20 pm, edited 2 times in total.
lowv
Posts: 5
Joined: Fri Jan 18, 2008 1:41 am

Re: Collision Problem

Post by lowv »

Wow, I was so caught up in this that I totally missed those two points. Thanks. The first one was just a careless mistake with the way I applied the "interactive torque". As for the second one, I'm not completely sure whether that isn't some indication of a more global problem. Anyway, I solved it by turning the perp radius vectors to the right instead of the left:

Code: Select all

 
 PA = Vector.NormalRight(Self.VertArr[vtx]) 
 PB = Vector.NormalRight(PBtt)
Now all collisions involving some angular component look good and you can see that it's actually not a collision problem:
http://www.2shared.com/file/2752524/f00 ... ation.html
Though there's still this odd interpenetration thing going on. And I'm not arguing that there could be a sign problem(angvel can most likely be ruled out), but which one? There aren't many more possibilities and besides that I have already tried all kinds of combinations for PA, PB, etc... but then everything just explodes. Isn't there anyone out there who has experienced a similar behaviour of his simulation?