Page 1 of 1
problems bouncing ball
Posted: Tue Mar 02, 2004 4:51 am
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!
Posted: Tue Mar 02, 2004 8:01 pm
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 :)
}
reflect
Posted: Tue Mar 02, 2004 10:02 pm
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();
}
Posted: Tue Mar 02, 2004 11:11 pm
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.
Posted: Wed Mar 03, 2004 2:48 am
by Guest
Schick, What is v in your reflect code above?
Posted: Wed Mar 03, 2004 2:55 am
by Guest
actually if you wouldn't mind could you explain your entine reflect code. Thanks
Aaarrrrrgggghhghh
Posted: Wed Mar 03, 2004 3:19 am
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();
}
Posted: Wed Mar 03, 2004 11:22 am
by Mercior
If its bouncing then the
must always be true.. could be a prescision thing - try something like:
Code: Select all
if (newLoc.getDistanceFrom(oldLoc + velocity) > 1)
Posted: Wed Mar 03, 2004 12:51 pm
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.
WHHAAAAAAAAAAAAHOOOOOOOOOOOOO!!!!!!!!!!
Posted: Wed Mar 03, 2004 3:26 pm
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:
ehmm
Posted: Wed Mar 03, 2004 3:43 pm
by schick
ok, need to check my math knowledge
![Smile :-)](./images/smilies/icon_smile.gif)
.
found the bug
Posted: Wed Mar 03, 2004 4:26 pm
by schick
Here we go, got the solution. Replace the one first mentioned with that one. That's it, what math is for
![Smile :-)](./images/smilies/icon_smile.gif)
.
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();
}
Posted: Wed Mar 03, 2004 5:25 pm
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!