Collision response , basic velocity inversion ..

Cf7283b96691896a34da7d3988e34092
0
gabdab 101 Aug 08, 2006 at 16:00

Hello,
I have a problem with collision response.
I implemented a simple velocity inversion when collision is checked .
Problem is that game controls get switched ( left is right and so ).
It looks like the condition of collision resolution is permanent .
Any idea how to make it temporary for the time of contact ?
( if (cres.NumPairs() > 0) in the code refers to the collision resolution condition ).

class MyCallback : public osg::NodeCallback {
public:
   MyCallback::MyCallback(tankInputDeviceStateType* tankIDevState
              //, float dt, osg::Timer_t start_tick
             )
    
   {
      tankInputDeviceState = tankIDevState;
   }
   
   
   
   


   virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
   {
       
        
    
    lastGameTime +=1;
    clock_t current = clock();
    difference = (current - lastGameTime)/lastGameTime*1000.0f ;
    std::cout<<difference<<"elapsed_time"<< std::endl;
    
    PQP_Collide(&cres,R1,T1,&ball1,
                      R2,T2,&ball2,
                     PQP_FIRST_CONTACT);

         
    if (cres.NumPairs() > 0)
    
    {
     
    posiz = -posiz;
    
     }
    
    if (tankInputDeviceState->moveFwdRequest)
    {
             T1[0] += posiz;
        
    }
    
    if (tankInputDeviceState->moveBwdRequest)
    {
             T1[0] -= posiz;
        
    }
    
    
    
    //osg matrix related to pqp matrix//
      osg::Matrix ex( R1[0][0], R1[0][1], R1[0][2], 0,
                      R1[1][0], R1[1][1], R1[1][2], 0,
                      R1[2][0], R1[2][1], R1[2][2], 0,
                      T1[0], T1[1], T1[2], 1.0 );
       
    
         
         
    osg::MatrixTransform *tx = dynamic_cast<osg::MatrixTransform *>(node);
    
    tx->setMatrix( ex );


        
            traverse( node, nv );
   }
   
    tankInputDeviceStateType* tankInputDeviceState; 

    private:
};

Thanks,
Gab-

2 Replies

Please log in or register to post a reply.

A9102969e779768e6f0b8cb87e864c94
0
dave_ 101 Aug 08, 2006 at 16:43

You need to change the way you’re applying your velocity.
The velocity should be reflected rather than inverted along the normal (ie the vector between the two objects) of the collision

And rather than applying the velocity based on the the buttons that are pressed you should really use

acceleration’ = sum of forces / mass
velocity’ = velocity + acceration * time delta
position’ = position + velocity * time delta

where time delta is the duration since the last update
and the forces are things like drag, friction and thrust (ie your engines power transmitted through the tracks)

Cf7283b96691896a34da7d3988e34092
0
gabdab 101 Aug 09, 2006 at 09:46

Hi dave_,
thanks for replying.

I am after just a basic first person shooter sort of collision response ( slide along walls, get over small obstacles and so forth), so I’ll leave dynamics for later.
[as explained here: [HTML]http://www.peroxide.dk/download/tutorials/tut10/pxdtut10.html[/HTML]

I was thinking about using a step variable ( time delta ) indeed to grab the difference between collide-position and last-position( before collision ) and normalize and invert that , so to move the moving ball away from the collision point ( no dynamics involved ).

So here is basically what I would like to do :

//compute a simple collision response.From VCOLLIDE demo
void ComputeResponse(Vector normal, Vector v, Vector *new_v)
{
  Vector v_normal = normal*(v/normal);
  Vector tan = ((normal*v)*normal);
  tan.normalize();
  Vector v_tan = tan*(v/tan);
  
  *new_v = v_normal*(-1) + v_tan;
//something to move ball .5f along normal away from collision point 
  
}
void CollisionTestReportAndRespond(void)
{
  ...
for (int j=0; j<no_of_colliding_pairs; j++)
    {
      cout<<"Detected collision between objects "<<vcrep[j].id1<<" and     "<<vcrep[j].id2<<"\n";  

      polyObject *p1 = GetObjectWithId(vcrep[j].id1);
     // polyObject *p2 = GetObjectWithId(vcrep[j].id2);

      Vector normal;
    
      normal = p1->position[step] - p1->position[oldstep];
      normal.normalize();
      ComputeResponse(normal, (p1->v), &(p1->v) );
      
    }

What I am doubious about is the step function..
But I guess this would suffice:

float step;
float oldstep;

In initialization part ( int main):
step = 0;

In callback function :
step = oldstep;
step = step+1;
maybe after rendering frame I should call :
oldstep = step to update not sure.

P.S:
What I’ve been figuring so far is to put the collision callback inside a void function so that when it gets called in the main callback I get a collision condition each time balls collide instead of a matter of fact ( balls collide constant ).
I am just a newbie with c++.

Gab-