Page 1 of 1
Collide with only specific CollisionGroup?
Posted: Wed Mar 27, 2013 5:39 am
by Telanor
I'm trying to set up a sort of invisible phantom shape that will fire an event whenever certain objects enter it. According to the documentation, personal rules take priority over group rules. Which means if I were to say personal: NoBroadPhase, group(A, B): Normal, the personal rule would result in NoBroadPhase for everything, right? So how can I set up CollisionGroup A to only collide with CollisionGroup B and not CollisionGroup C, D, E, etc
Re: Collide with only specific CollisionGroup?
Posted: Wed Mar 27, 2013 4:16 pm
by Norbo
Here's a few options:
1) Assign collision group rules between all relevant collision group pairs. Leave Personal rule as 'defer.' This is sometimes feasible if the group count is low enough.
2) CollisionRules.DefaultCollisionRule defaults to Normal. This is chosen if all collision rule calculations return 'Defer.' Change it to CollisionRule.NoBroadPhase and specify rules to guarantee that things that need to collide do collide. This inversion strategy is sometimes useful depending on the filter requirements.
3) Change the CollisionRules.CollisionRuleCalculator delegate to your own custom handler. The default looks like this:
Code: Select all
public static CollisionRule GetCollisionRuleDefault(ICollisionRulesOwner aOwner, ICollisionRulesOwner bOwner)
{
var a = aOwner.CollisionRules;
var b = bOwner.CollisionRules;
CollisionRule pairRule = GetSpecificCollisionRuleDefault(a, b);
if (pairRule == CollisionRule.Defer)
{
pairRule = GetPersonalCollisionRuleDefault(a, b);
if (pairRule == CollisionRule.Defer)
pairRule = GetGroupCollisionRuleDefault(a, b);
}
if (pairRule == CollisionRule.Defer)
pairRule = DefaultCollisionRule;
return pairRule;
}
For example, if you wanted group rules to take precedence over personal rules, swap the order of the GetPersonalCollisionRuleDefault and the GetGroupCollisionRuleDefault.
This delegate is called quite frequently, however; try to avoid doing any heavy lifting within it.
Re: Collide with only specific CollisionGroup?
Posted: Thu Mar 28, 2013 1:38 am
by Telanor
For option 1, what counts as "relevant collision group pairs"? If I want group B to collide with ONLY group A and no other groups, would I just set group B's personal rule to defer and then create a group(A, B) rule? Does it just default to NoBroadPhase if no rule applies?
Re: Collide with only specific CollisionGroup?
Posted: Thu Mar 28, 2013 1:50 am
by Norbo
If all specific/personal/group tests result in Defer, then it defaults to Normal. So, if you want AB to collide and AC, AD, and AE to not collide, you would need a NoBroadPhase rule for the pairs AC, AD, and AE (and no overriding personal/specific Normal collision rules).
You can change this default, as described in #2.
Re: Collide with only specific CollisionGroup?
Posted: Thu Mar 28, 2013 1:59 am
by Telanor
Ah, so that could get to be a pain if there's a lot of groups.
Perhaps I should rephrase my original question. Right now I just have the objects in group B set to NoNarrowPhaseUpdate and then I hook the ContactCreated event for items in group A and do the checks in there (I'm not actually using groups even). The reason I want to move away from doing it this way is because I keep having to exclude/filter-out the "detector" shapes from group B when doing raycasts and when doing other collision checking events. Are there other efficient ways of detecting an object entering a shape? I don't need (or want) any collision response, I only want to know when an object from group A has entered.
Re: Collide with only specific CollisionGroup?
Posted: Thu Mar 28, 2013 2:33 am
by Norbo
As far as entities go, if you want to detect contacts without collision response, then some application of collision rules is the correct approach.
The DetectorVolume is another option which sidesteps most of the collision rules issues. It is not an entity. It is incapable of generating contacts; its sole purpose is checking for intersection and containment.
However, it is mesh based. It will probably be a bit less speedy than if the detector was just a simple primitive, like an entity using a BoxShape.
Also, those DetectorVolumes still show up in ray casts and queries. The fact that they are not entities could ease the filtering process a little, but it would be just as easy to filter based on some tag information which marks the object as a 'detector'.
Re: Collide with only specific CollisionGroup?
Posted: Thu Mar 28, 2013 10:09 am
by Telanor
I guess for now I'll use option 1. Hopefully I don't find the need for a lot of different groups. Thanks again Norbo
Re: Collide with only specific CollisionGroup?
Posted: Thu Mar 28, 2013 10:39 pm
by Telanor
Hmm, for some reason I don't seem to be getting any collision events firing. I set the group up like this:
Code: Select all
CollisionRules.CollisionGroupRules.Add(new CollisionGroupPair(ItemGroup, PlayerItemDetectorGroup), CollisionRule.Normal);
The detector shape is setup like this:
Code: Select all
ItemCollisionShape.CollisionInformation.CollisionRules.Personal = CollisionRule.Defer;
ItemCollisionShape.CollisionInformation.CollisionRules.Group = Physics.Physics.PlayerItemDetectorGroup;
ItemCollisionShape.CollisionInformation.Events.PairTouched += EventsOnPairTouched;
And the item is simply:
Code: Select all
itemEntity.CollisionInformation.CollisionRules.Group = Physics.Physics.ItemGroup;
Re: Collide with only specific CollisionGroup?
Posted: Thu Mar 28, 2013 10:57 pm
by Norbo
It doesn't seem like the collision rules have anything to do with the events not firing. Assuming the default collision rule is still set to Normal, all of those collision rules don't actually change any behavior. If the default is now NoBroadPhase, that group rule (assuming nothing else overrides it) should ensure they collide, and the event should still fire. The event system doesn't really interact with collision rules otherwise, so I'm not sure why it wouldn't be firing.