Jump to content


Collision response , basic velocity inversion ..


2 replies to this topic

#1 gabdab

    New Member

  • Members
  • Pip
  • 7 posts

Posted 08 August 2006 - 04:00 PM

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 dave_

    Senior Member

  • Members
  • PipPipPipPip
  • 584 posts

Posted 08 August 2006 - 04:43 PM

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)

#3 gabdab

    New Member

  • Members
  • Pip
  • 7 posts

Posted 09 August 2006 - 09:46 AM

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:
http://www.peroxide....0/pxdtut10.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-





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users