problems bouncing ball

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Post Reply
thesmileman
Posts: 360
Joined: Tue Feb 10, 2004 2:20 am
Location: Lubbock, TX

problems bouncing ball

Post by thesmileman »

I know this is probibly a sad way to do this(if there is a better way,which I am sure there is let me know) thanks.

I am trying to get a fireball to change direction when it collides with anything. I was hoping Irrlicht had a onCollision() call but no dice. I already have generic collision detection working (aka ball hits wall and stops).

What I decided to do was to get the position of where my fireball should be (currentPosition+direction) and then update the position of the fireball with this new position. Then check the position after it has been updated and if this position is not the same as (position+direction) then collision has occured.

This did not work and I have tried several different ways of doing the above and I get the same result, (the fireball just goes back and forth in a small space in midair). It seems that when I change the direction it just changes right back. Here is my code:

*NOTE: ps4 is my fireball

Code: Select all

while(irrDevice->run()) { 
   //save position where ball should be
   newLocation = newLocation = ps4->getPosition()+direction;
   
   // move fireball
   ps4->setPosition(newLocation);
   
   //Do scenecrap
   irrDriver->beginScene(true,true,0);      
   irrSceneMgr->drawAll();
   irrDriver->endScene();

   //Check for collision
   if(newLocation != ps4->getPosition())
      direction.invert(); //collision detected so change direction
      // I know the above does not make the ball bounce but just to test this 
      // code I am seeing if I can send the ball back in the direction it came
}
I tried using the getResultPosition() but it did not change the direction of the ball just mad it slide across the object.

Thanks for any help!
Mercior
Posts: 100
Joined: Tue Feb 24, 2004 1:53 am
Location: UK
Contact:

Post by Mercior »

My advice would be to manage the collision manually (excuse the variables, this is pasted from one of my projects):

Code: Select all


	newloc = world->smgr->getSceneCollisionManager()->getCollisionResultPosition(world->g_selector, 
	loc, vector3df(30,50,30), velocity,					// position, radius, move vector
	triout, outFalling, 0.0005f, vector3df(0, -10, 0));	// gravity

if (newloc != loc + velocity)
{
  // it collided.. invert the velocity vector or whatever :)
}
schick
Posts: 230
Joined: Tue Oct 07, 2003 3:55 pm
Location: Germany
Contact:

reflect

Post by schick »

Maybe the vector template should have a reflect( vector<T> n) function. something like:

Code: Select all


reflect( n)
{
  normalize();		  
  n.normalize();
  return (v - n * 2.0 * (v.dotProduct( n))) * v.getLength();
}

Phunk
Posts: 78
Joined: Sun Dec 14, 2003 8:18 pm
Location: The Netherlands

Post by Phunk »

I think that the col. det. that you want is too advanced for the irrlicht engine, what you described, that the ball just slides at the wall is the result of the col. det. in irrlicht, as it just looks at the pos that the ball has, and then modifies the vector to make it not go into the wall, and leaving the remaining values unchanged, thus causes sliding. can't you use the getResultPosition() to check if a collision is happening, and then the vector returned minus "your position" should be the normal of the wall that you will want to bounce against. then you can use the code that is submitted above to create the right reflection.
Guest

Post by Guest »

Schick, What is v in your reflect code above?
Guest

Post by Guest »

actually if you wouldn't mind could you explain your entine reflect code. Thanks
thesmileman
Posts: 360
Joined: Tue Feb 10, 2004 2:20 am
Location: Lubbock, TX

Aaarrrrrgggghhghh

Post by thesmileman »

Thanks guys for your help but I am still getting the same result: the ball justs bounces back and forth is a very small spot in midair. Here is my code if anyone can tell me whats wrong.

*note I do not want gravity.

Also what is the triout in the getCollisionResultPosition() and do I need it? The API says its optional but compiler will not accept function without something there.

Code: Select all

core::vector3df newLoc, oldLoc, velocity;
oldLoc = ps4->getPosition();
velocity = core::vector3df(-5,0,5);
bool outFalling = false;
core::triangle3df triout; 
	
while(irrDevice->run()) { 
   newLoc = irrSceneMgr->getSceneCollisionManager()->getCollisionResultPosition(metaSelector, 
            oldLoc, core::vector3df(6,6,6), velocity, triout, 
            outFalling, 0.5f,core::vector3df(0, 0, 0));		
   if (newLoc != oldLoc + velocity) 
      velocity.invert();

   ps4->setPosition(newLoc);
   oldLoc = newLoc;

   irrDriver->beginScene(true,true,0);      
   irrSceneMgr->drawAll();
   irrDriver->endScene();
}
Mercior
Posts: 100
Joined: Tue Feb 24, 2004 1:53 am
Location: UK
Contact:

Post by Mercior »

If its bouncing then the

Code: Select all

if (newLoc != oldLoc + velocity)
must always be true.. could be a prescision thing - try something like:

Code: Select all

if (newLoc.getDistanceFrom(oldLoc + velocity) > 1)
schick
Posts: 230
Joined: Tue Oct 07, 2003 3:55 pm
Location: Germany
Contact:

Post by schick »

@Guest

"v is the vector of your velocity, n is supposed to be the normal of the plane you want to collide with"

@thesmileman

Code: Select all

      // temp variables
      triangle3d<f32> triout, triorg;
      bool isfalling = false;
 
      ISceneCollisionManager* collmgr = SceneManager->getSceneCollisionManager(); 

      setPosition( collmgr->getCollisionResultPosition( World,
                                                        getPosition(),
                                                        Radius,
                                                        Velocity,
                                                        triout,
                                                        isfalling,
                                                        0.0005f, // working
                                                        Gravity));

      if( triorg != triout)
        {		
          // well, we collided 
          vector3df v = Velocity.normalize();		  
          vector3df n = triout.getNormal().normalize();
          Velocity = (v - n * 2.0 * (v.dotProduct( n))) * v.getLength();
		  
        }
 
Well, that code is supposed to be in the OnPostRender() function of your scenenode.
thesmileman
Posts: 360
Joined: Tue Feb 10, 2004 2:20 am
Location: Lubbock, TX

WHHAAAAAAAAAAAAHOOOOOOOOOOOOO!!!!!!!!!!

Post by thesmileman »

Sweet Mercior thanks for the help that worked great! Also thanks schick for the comparision of the triangle with the old triangle that also worked and I am using the later method.

Schick, is there any reason why after the first bounce the ball slows down? It only happens after the first bounce and the speed of the ball stays the same.

Also If anyone is trying to use Schicks code don't forget at the end of the code you must set the old triangle to the new triangle as such:

Code: Select all

triorg = triout;
schick
Posts: 230
Joined: Tue Oct 07, 2003 3:55 pm
Location: Germany
Contact:

ehmm

Post by schick »

ok, need to check my math knowledge :-).
schick
Posts: 230
Joined: Tue Oct 07, 2003 3:55 pm
Location: Germany
Contact:

found the bug

Post by schick »

Here we go, got the solution. Replace the one first mentioned with that one. That's it, what math is for :-).

Code: Select all

      if( triorg != triout)
        {		
          // well, we collided 
          vector3df n = triout.getNormal().normalize();
          Velocity = (Velocity - n * 2.0 * (Velocity.dotProduct( n))).normalize() * Velocity.getLength();
        }
thesmileman
Posts: 360
Joined: Tue Feb 10, 2004 2:20 am
Location: Lubbock, TX

Post by thesmileman »

Sweet that worked. I had gotten around it by just multiplying the velocity by a speed vector which worked fine except for some reason, everyonce in a while the ball would bounce straight back as though I had used velocity.invert() but this code fixed it.

I really wished I had paid more attention in my Liner Algebra class as it would come in really handy with all the 3D programming.

Thanks again!
Post Reply