contactcallback issue

mako

17-04-2007 18:05:22

well, lets suppose that I have n meteor rocks that will fall on the ground, and I'll be using a contactCallback class called meteorRockCallBack.

it will play a sound when the rock reaches the ground (an explosion sound) the problem is that when it fall on the ground, the meteor rock stay in there. and keep the contact. so the sound does not stop.
how can I limit the sound to the first contact only?

remember that I have many rocks and not just only one.
p.s. the rock has the same materialID of the ground, and the rocks might shock on the sky, and emit the sound explosion too.

could u help me?

thanks in advance

Game_Ender

17-04-2007 22:04:57

Store state in the whatever class represents the rock, and add it as user data on the body. Then in the callback retrieve that user data and keep track of how many times the sound has been played.

mako

18-04-2007 04:39:02

cool, this might help, but is there a way to set to false in case the contact stop?

Game_Ender

18-04-2007 05:59:08

That I have not figured out yet, its quite unfortunately that you don't have good access to Newtons internal BSP. Despite what is said on the Newton forums without official support for triggers I don' think can figure out when something leaves an area.

EDIT: Check that, you have to do some book keeping, but it is possible.

mako

18-04-2007 12:53:50

how does the userEnd method works?
I thought that it would be called when the contacts ends.. but it's calling after 4 calls to userProcess and after 1 call to userBegin

mako

18-04-2007 15:38:20

hey Game_Ender, I figure out a way to do this...(it's not the best)

I created a timer in my class that has my body, and I reset the timer at every contact

and in the framestarted() method of my frameListener

I test if the timer.getMiliseconds()>100;

if the condition is true, is because the time is not reseted, so its not in contact anymore. so I set to false the flag. xD

its kinda cheater way. but it worked for me..
what do u think?

CagedFury

26-04-2007 03:40:29

Could you reset the callback to the standard callback from within your custom callback, that way the custom callback would execute everything it has to and then just switch to the default (of course this means the callback cant be used to do anything else fancy.. like play a sound when the player stes on it or something)

JackyE

29-04-2007 23:09:09

Maybe assign a different materialID to you meteor. That way the contactcallback is not called. And with a little extra code, you character will still say Ouch! when walking over the burning meteor.

Game_Ender

30-04-2007 01:15:23

I have a good algorithm for determining when bodies leave and enter a trigger area:
* Your contact callback maintains a Body -> Bool map
* Before every world update map every body in the map to "False"
* Everytime the userProcess method is called map the body that contacts with your trigger to "True" in your map. If the body was not in map already fire off your "enter event".
* After the the world update iterate over the map and fire off the "exit event" for each body still mapped to False (ie it didn't contact that update, so it must be outside the trigger). Then remove all bodies marked false from the map.

I currently use this to great effect in my application.

oddrose

17-07-2007 18:12:38

I have a good algorithm for determining when bodies leave and enter a trigger area:
* Your contact callback maintains a Body -> Bool map
* Before every world update map every body in the map to "False"
* Everytime the userProcess method is called map the body that contacts with your trigger to "True" in your map. If the body was not in map already fire off your "enter event".
* After the the world update iterate over the map and fire off the "exit event" for each body still mapped to False (ie it didn't contact that update, so it must be outside the trigger). Then remove all bodies marked false from the map.

I currently use this to great effect in my application.


I thought about using that method as well but I didn't want to put the checking outside of the callback class. So I came up with a different solution. (When the app starts timesCollided = 0)


int CollisionHandler::userProcess()
{
if(timesCollided == 0) {

// We have collision!
}

timesCollided++;

return 1;
}

void CollisionHandler::userEnd()
{
if(timesCollidedLast == timesCollided) {

timesCollided = 0;
}

timesCollidedLast = timesCollided;
}


Works great so far...:)

walaber

17-07-2007 19:39:29

also you can have a look at the velocity of the collision, and only play a sound if the velocity is > some value.. you can even adjust the volume of the sound based on the velocity of the collision.

here's a quick recap of the 2 callback functions.

userBegin() called when the AABB's of the bodies overlap, signifying that these 2 bodies might collide during this update.

userProcess() called for each discreet collision/contact between the bodies during this update. here you should store any information you want, like remembering (with a member variable) the highest velocity, etc

userEnd() is called once after all of this to give you a chance to "act" upon the results.


for example, if your callback class has a member float variable called "largestVelocity", you would do this:

in userBegin() - set largestVelocity to 0.

in userProcess() if the contact velocity > largestVelocity, set largestVelocity to this contact's velocity.

in userEnd() if largestVelocity is > some value, play an impact sound, or trigger some game logic.