CustomTriggerManager misses exit events

Report any bugs here and we'll post fixes

Moderators: Sascha Willems, Thomas

CustomTriggerManager misses exit events

Postby aitzolmuelas » Wed Apr 08, 2015 1:22 pm

Hi, there is a problem in the way CustomTriggerManager is implemented, it can be tested with the Arquimedes sample in the demos: place a breakpoint in the exit event (CustomTriggerManager.cpp: line 92) and then grab one of the objects floating in the 'water' and throw it out. The exit event is sometimes not sent. This is because if the contact pair becomes invalid the same frame when the two bodies stop intersecting in the broadphase, then there is no contact pair to 'tell you' the contact has ended (the contact pair has ceased to be before it could be checked). One would need to go over the dictionary in the trigger again and check if any of the previous triggering bodies no longer have an associated contact pair with the trigger.
I have managed to fix it in the custom trigger manager I have had to implement in my project, however I have a suggestion: I had a similar problem with the previous physics engine I was using (Bullet, to be precise). The solution I came up with is basically to have actual trigger events/callbacks from within the physics engine itself. This was possible for almost no cost by using the 'valid' flag in the persistent contact pair (true when the shapes collide, not just the broadphase AABBs): when the flag changes value (which the engine checks anyway) if any of the colliding bodies is marked as trigger (this had to be added) then send the appropriate message/callback.
I don't know if this would be possible within the newton architecture, but it would make having reliable trigger events almost trivial from the user's side, no dictionaries and extra memory/computing needed (and I think it would have little to no overhead).
aitzolmuelas
 
Posts: 78
Joined: Wed Mar 25, 2015 1:10 pm

Re: CustomTriggerManager misses exit events

Postby Julio Jerez » Wed Apr 08, 2015 1:29 pm

first let us see what the Bug is. I will test tonight.

Second yes you idea sound very good, do you understand how Listeners work in the engine.
The trigged manage is actually a listener.

it should be easy to implement you idea and register that instead of the one in the joint library
Julio Jerez
Moderator
Moderator
 
Posts: 11039
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: CustomTriggerManager misses exit events

Postby Julio Jerez » Wed Apr 08, 2015 1:35 pm

aitzolmuelas wrote:The solution I came up with is basically to have actual trigger events/callbacks from within the physics engine itself. This was possible for almost no cost by using the 'valid' flag in the persistent contact pair (true when the shapes collide, not just the broadphase AABBs): when the flag changes value (which the engine checks anyway) if any of the colliding bodies is marked as trigger (this had to be added) then send the appropriate message/callback.


yes that sound awesome. a narrow phase call back for triggers, :D
the engine has a narrow phase callback for material pairs, by that is but this one should be per object. yes that sounds very good idea. It simply the triggers a lot too
Julio Jerez
Moderator
Moderator
 
Posts: 11039
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: CustomTriggerManager misses exit events

Postby aitzolmuelas » Wed Apr 08, 2015 1:37 pm

It was the simplest approach I could come up with at the time, but glad you like the idea ^_^
aitzolmuelas
 
Posts: 78
Joined: Wed Mar 25, 2015 1:10 pm

Re: CustomTriggerManager misses exit events

Postby Julio Jerez » Wed Apr 08, 2015 1:41 pm

basically it would be a callback in the Body, and the call back is called each time tow bodies
activate a joint, or deactivate a joint
something like
OnBodyJoint (body*, joint, bool state)

an when two body crate a joint is a body se that point the function is called whe the Joint is active, and when the joint is deactivated

I a way it renders the trigger manager obsoleted, awesome :mrgreen:

I am not even going to fix the Bug I will simply do that.
Julio Jerez
Moderator
Moderator
 
Posts: 11039
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: CustomTriggerManager misses exit events

Postby Julio Jerez » Thu Apr 16, 2015 10:44 am

Ok I think I have this fixed now.

Basically it was possible that a joint was send to be deleted while it contact active flag was true.
This could happen if the pair was no seen by the brad phase and the contact was never validated.

basically the contact garbage collector, has to simple invalidate the joint and delay it destruction, and that fixed the bug, no need for the call back

Please try again.
Julio Jerez
Moderator
Moderator
 
Posts: 11039
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: CustomTriggerManager misses exit events

Postby aitzolmuelas » Fri Apr 17, 2015 6:28 am

Basically it was possible that a joint was send to be deleted while it contact active flag was true.
This could happen if the pair was no seen by the brad phase and the contact was never validated.

Yes, I probably did not explain myself clearly in the first post, but this is exactly what I was trying to describe (it is, after all, a very generic physics broadphase issue).
Secondly, I did not argument in favour of the callback as a fix (as I said, I had managed to get triggers working properly by checking contacts vs a dictionary, and then again the dictionary vs the contacts to ensure there are no missing exit events). My argument is in favour of 'comfort': even with your latest fix, I see 3 problems in having to use a dictionary-based trigger manager (not severe, but could be avoided):

- Memory overhead due to storing a dictionary for each trigger entity.

- CPU overhead due to checking contacts vs dictionaries each frame.

- In case a non-dynamically allocated dictionary is preferred, this imposes a limit in the number of bodies a trigger can detect simultaneously (size of the dictionary, 32 in the JointsLibrary Trigger Manager if I am not mistaken).

While non of these issues are absolutely critical, a callback dispatched when contacts become active/inactive would solve the problem avoiding the overheads and restrictions. It doesn't even need to be a per-body callback, it could be global, or even a per-material callback (like applyForceAndTorque).
Again, I am no expert, so I don't know if this would cause other unforeseen overheads within Newton, but from my perspective it looks like a win-win situation.
aitzolmuelas
 
Posts: 78
Joined: Wed Mar 25, 2015 1:10 pm

Re: CustomTriggerManager misses exit events

Postby Julio Jerez » Fri Apr 17, 2015 10:14 am

where do you get the idea of the triggers only having room for 32 objects.
you have an older version

this is the class that implement a controller
Code: Select all
class CustomTriggerController: public CustomControllerBase
{
   public:
   CUSTOM_JOINTS_API CustomTriggerController();
   CUSTOM_JOINTS_API ~CustomTriggerController();

   CUSTOM_JOINTS_API void Init (NewtonCollision* const convexShape, const dMatrix& matrix, void* const userData);
   CUSTOM_JOINTS_API virtual void PreUpdate(dFloat timestep, int threadIndex);
   CUSTOM_JOINTS_API virtual void PostUpdate(dFloat timestep, int threadIndex);
   
   private:
   dTree<NewtonBody*,NewtonBody*> m_manifest;
   friend class CustomTriggerManager;
};


each body in the controller is stored in a container which have no size limit
plus the update does no integrate over the contacts, it iterate one the contact joints.

I agree with you that the logic could be simpler if the concept was conceived from the original design. A call back would some the problem better, but it would still have to implement the same logic, for example the trigger get three type of event, enter, exit, while in trhigger.

The this one will would required the implementation of some logic.
the engine already has the joint - body graphs, what is does no has is the we to identify the a graph node as a trigger.


at the moment there are too many structure to maintain between the broad phase and the dynamic Phase. In the next few day I will make a change to the brad phase to try to make update less
right now the broad phase iterate over the query aabb tree to check for all pairs, but this may no be necessary if each objet can validate it contacts each time the change their transform

after doing that I see if I add the trigger type as a newton type, that way the implementation will be just going over the graph.
Julio Jerez
Moderator
Moderator
 
Posts: 11039
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: CustomTriggerManager misses exit events

Postby aitzolmuelas » Fri Apr 17, 2015 11:25 am

where do you get the idea of the triggers only having room for 32 objects.

Sorry, my mistake, when I saw in the code that the dTree template in
Code: Select all
dTree<NewtonBody*,NewtonBody*> m_manifest;

has a third (default) integer argument (32) I incorrectly assumed it was static fixed size (at any rate, if it's not fixed then it allocates/reallocates memory).

but it would still have to implement the same logic

Same logic, but not same processing: as I understand (correct me if I am wrong), during the collision update within Newton, it has to be determined when a contact joint has become active/inactive (I assume so, because there is a boolean flag which is being toggled on/off). So I do not see why the trigger manager has to determine it again by checking contact joints against a dictionary. I know I am being a bit obsessive with this (as I mentioned, the overhead is not that much), but it just bothers me that the trigger manager is basically re-computing information that has already been computed inside Newton.

what is does no has is the we to identify the a graph node as a trigger.

Hmmm... that is a problem ;P I guess a set of global callbacks (for enter/exit/inside events, or a single callback with an 'event_type' argument) to be called for each body might be a bit overkill (maybe not), that's why I suggested having a callback set per material, but maybe it is not that simple to do that and keep the API clean and clear (I am a bit undecided on how to consider the issue myself :P). However I like your idea of having triggers as a Newton type.

this may no be necessary if each objet can validate it contacts each time the change their transform

Cool, I think Bullet does something similar, based on my experience with it (and despite having abandoned Bullet because of several issues, I admit their broadphase is very fast even single-threaded).

at the moment there are too many structure to maintain

I understand that. Newton is indeed an impressive piece of software, and I am quite amazed that you dedicate so much effort to maintaining it and still find time to reply to my rantings XD so I do not want to pressure you; you have my most sincere admiration! Feel free to let me know if I can help in any way (besides reporting bugs I might find) ^_^
aitzolmuelas
 
Posts: 78
Joined: Wed Mar 25, 2015 1:10 pm

Re: CustomTriggerManager misses exit events

Postby Julio Jerez » Fri Apr 17, 2015 1:35 pm

the in parameter in the template library, is a actually very good trick. 8) glad you saw that
Basically the container library use free list. however naïve contains with free list can use lots of memory that, since the almost never release memory unless it is explicitly done.
people in the console world tend to make containers of Fix size, and I really do not like that because you never know when a container is either too big or too small, specialty hash map why are so popular among console developers.

My approach is to have a container that adapt to the situation by that can be very effect handling memory.
for that I using the free list, but the number of element in the free list is integer multiple of some number. so memory is free each time the free list pass that size, or a new batch is added each time it need more elements.
I test this we an application that I have the tool about 4 hour to parse a grammar, this was because II was using stdStream to store token and rules. after I made the dStream class the running time was cut to about one hour, the I extended to the other containers, and the running time when down to about 14 to 20 minutes. Very rare I see such dramatic speed up.

The is also another benefit for allocation the memory in burst, the has to do with how memory manage word. the try to coalesce free chunk into larger chunks, so when you allocate runs of memory block of equal size that make the memory manager much more efficient.

If I have to do this again I would get rid of the Newton Memory manager and simple use the dContainers.

I have being thinking about removing the prophase update for a long time, I do no like the fact that it need an auxiliary array for colleting the pairs, when the is already a graphs that have all those
pair.

There is some funtionlity that does ta already, the debrid chunk, update their contact when the get added to the bradphase, I jsu nee to consolidate the tow methods.
There are some good side savig.

for example when the broadphase get a pair, it does no know f that pair already has a joint, so it have to go over the joint list check in a joint exist the connect the two body.

this usually fast, because in general a body is conned to maybe a dozen joints. whoever if the body happen to be a backgound object like a building or a terrain, the is may have thousand of joints.
so solve that I have to have tow function tat walk the graph in different way, with some subtleties.

in the new idea it would no matter, because only bodies that change position make update contacts
so a terrain piece is move it will get the contact but that is what users want to do. normally moving objects will che their small lit of joints.
Julio Jerez
Moderator
Moderator
 
Posts: 11039
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: CustomTriggerManager misses exit events

Postby aitzolmuelas » Wed Jun 10, 2015 12:05 pm

Julio Jerez wrote:Basically it was possible that a joint was send to be deleted while it contact active flag was true.
This could happen if the pair was no seen by the brad phase and the contact was never validated.

basically the contact garbage collector, has to simple invalidate the joint and delay it destruction, and that fixed the bug, no need for the call back


I am having the following problem now: if a trigger is destroyed while a body is inside it, everything is OK; however, if the body is destroyed while inside the trigger, the trigger never realizes it, and remains active (maybe the destruction is not delayed in this case? I haven't been able to test it much yet).
aitzolmuelas
 
Posts: 78
Joined: Wed Mar 25, 2015 1:10 pm

Re: CustomTriggerManager misses exit events

Postby Julio Jerez » Wed Jun 10, 2015 1:06 pm

oh yes that can happens. I though there notify function on destroy callback should handle that.
but yes you are correct, tah implye stha the use will add a desteruto call back.

I need to add an Ondestroycall back to the Listener manager, and when a body is detroying it should call the destroy callback on each listener and eh body.
that will let ether listenerr remove the body.

good catch.
Julio Jerez
Moderator
Moderator
 
Posts: 11039
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: CustomTriggerManager misses exit events

Postby Julio Jerez » Thu Jun 11, 2015 3:56 am

Ok it turn out that the trigger do have the OnBody destroy callback, It did not have to add anything.

The trigger call back had a bug thought, when the body die in the trigger I was sending OnExit event but that was a mistake, a body dying inside the trigger does not mean it exited the trigger.

for you case you need to overload the OnBody Destroy callback, like this

Code: Select all
void MyThiggerManager::OnDestroyBody (NewtonBody* const body)
{
        // body was delete inside a trigger, do what you need to do here
        ....

      //call base class callback
        CustomTriggerManager::OnDestroyBody (body);
}
Julio Jerez
Moderator
Moderator
 
Posts: 11039
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: CustomTriggerManager misses exit events

Postby aitzolmuelas » Thu Jun 11, 2015 4:20 am

Is the callback called for any destroyed body?
aitzolmuelas
 
Posts: 78
Joined: Wed Mar 25, 2015 1:10 pm

Re: CustomTriggerManager misses exit events

Postby Julio Jerez » Thu Jun 11, 2015 9:57 am

yes, you can see it here

Code: Select all
void dgWorld::DestroyBody(dgBody* const body)
{
   for (dgListenerList::dgListNode* node = m_postListener.GetLast(); node; node = node->GetPrev()) {
      dgListener& listener = node->GetInfo();
      if (listener.m_onBodyDestroy) {
         listener.m_onBodyDestroy (this, node, body);
      }
   }

   for (dgListenerList::dgListNode* node = m_preListener.GetLast(); node; node = node->GetPrev()) {
      dgListener& listener = node->GetInfo();
      if (listener.m_onBodyDestroy) {
         listener.m_onBodyDestroy (this, node, body);
      }
   }
 
Julio Jerez
Moderator
Moderator
 
Posts: 11039
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Next

Return to Bugs and Fixes

Who is online

Users browsing this forum: No registered users and 4 guests