-
-
Notifications
You must be signed in to change notification settings - Fork 251
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement interaction groups test mode and cofficient combine rule #741
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -7,13 +7,18 @@ | |||||||||||||||||||||||||
/// - The interaction groups filter. | ||||||||||||||||||||||||||
/// | ||||||||||||||||||||||||||
/// An interaction is allowed between two filters `a` and `b` when two conditions | ||||||||||||||||||||||||||
/// are met simultaneously: | ||||||||||||||||||||||||||
/// are met simultaneously for [`InteractionTestMode::AND`] or individually for [`InteractionTestMode::OR`]:: | ||||||||||||||||||||||||||
/// - The groups membership of `a` has at least one bit set to `1` in common with the groups filter of `b`. | ||||||||||||||||||||||||||
/// - The groups membership of `b` has at least one bit set to `1` in common with the groups filter of `a`. | ||||||||||||||||||||||||||
/// | ||||||||||||||||||||||||||
/// In other words, interactions are allowed between two filter iff. the following condition is met: | ||||||||||||||||||||||||||
/// In other words, interactions are allowed between two filter iff. the following condition is met | ||||||||||||||||||||||||||
/// for [`InteractionTestMode::AND`]: | ||||||||||||||||||||||||||
/// ```ignore | ||||||||||||||||||||||||||
/// (self.memberships & rhs.filter) != 0 && (rhs.memberships & self.filter) != 0 | ||||||||||||||||||||||||||
/// (self.memberships.bits() & rhs.filter.bits()) != 0 && (rhs.memberships.bits() & self.filter.bits()) != 0 | ||||||||||||||||||||||||||
/// ``` | ||||||||||||||||||||||||||
/// or for [`InteractionTestMode::OR`]: | ||||||||||||||||||||||||||
/// ```ignore | ||||||||||||||||||||||||||
/// (self.memberships.bits() & rhs.filter.bits()) != 0 || (rhs.memberships.bits() & self.filter.bits()) != 0 | ||||||||||||||||||||||||||
/// ``` | ||||||||||||||||||||||||||
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] | ||||||||||||||||||||||||||
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] | ||||||||||||||||||||||||||
|
@@ -23,25 +28,39 @@ pub struct InteractionGroups { | |||||||||||||||||||||||||
pub memberships: Group, | ||||||||||||||||||||||||||
/// Groups filter. | ||||||||||||||||||||||||||
pub filter: Group, | ||||||||||||||||||||||||||
/// Interaction test mode | ||||||||||||||||||||||||||
pub test_mode: InteractionTestMode, | ||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] | ||||||||||||||||||||||||||
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, Default)] | ||||||||||||||||||||||||||
/// Specifies which method should be used to test interactions | ||||||||||||||||||||||||||
pub enum InteractionTestMode { | ||||||||||||||||||||||||||
/// Use [`InteractionGroups::test_and`]. | ||||||||||||||||||||||||||
#[default] | ||||||||||||||||||||||||||
AND, | ||||||||||||||||||||||||||
/// Use [`InteractionGroups::test_or`]. | ||||||||||||||||||||||||||
OR, | ||||||||||||||||||||||||||
Comment on lines
+40
to
+43
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The case is not idiomatic:
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @Vrixyz Can you check why the non-idiomatic case wasn’t caught by CI please? I feel like this should have been a warning (that is denied in CI). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That would be caught with this clippy lint: https://rust-lang.github.io/rust-clippy/master/index.html#upper_case_acronyms with additional options in
Unfortunately, This option also warns against |
||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
impl InteractionGroups { | ||||||||||||||||||||||||||
/// Initializes with the given interaction groups and interaction mask. | ||||||||||||||||||||||||||
pub const fn new(memberships: Group, filter: Group) -> Self { | ||||||||||||||||||||||||||
pub const fn new(memberships: Group, filter: Group, test_mode: InteractionTestMode) -> Self { | ||||||||||||||||||||||||||
Self { | ||||||||||||||||||||||||||
memberships, | ||||||||||||||||||||||||||
filter, | ||||||||||||||||||||||||||
test_mode, | ||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||
Ughuuu marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
/// Allow interaction with everything. | ||||||||||||||||||||||||||
pub const fn all() -> Self { | ||||||||||||||||||||||||||
Self::new(Group::ALL, Group::ALL) | ||||||||||||||||||||||||||
Self::new(Group::ALL, Group::ALL, InteractionTestMode::AND) | ||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
/// Prevent all interactions. | ||||||||||||||||||||||||||
pub const fn none() -> Self { | ||||||||||||||||||||||||||
Self::new(Group::NONE, Group::NONE) | ||||||||||||||||||||||||||
Self::new(Group::NONE, Group::NONE, InteractionTestMode::AND) | ||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
/// Sets the group this filter is part of. | ||||||||||||||||||||||||||
|
@@ -59,21 +78,41 @@ impl InteractionGroups { | |||||||||||||||||||||||||
/// Check if interactions should be allowed based on the interaction memberships and filter. | ||||||||||||||||||||||||||
/// | ||||||||||||||||||||||||||
/// An interaction is allowed iff. the memberships of `self` contain at least one bit set to 1 in common | ||||||||||||||||||||||||||
/// with the filter of `rhs`, and vice-versa. | ||||||||||||||||||||||||||
/// with the filter of `rhs`, **and** vice-versa. | ||||||||||||||||||||||||||
#[inline] | ||||||||||||||||||||||||||
pub const fn test(self, rhs: Self) -> bool { | ||||||||||||||||||||||||||
// NOTE: since const ops is not stable, we have to convert `Group` into u32 | ||||||||||||||||||||||||||
// to use & operator in const context. | ||||||||||||||||||||||||||
pub const fn test_and(self, rhs: Self) -> bool { | ||||||||||||||||||||||||||
(self.memberships.bits() & rhs.filter.bits()) != 0 | ||||||||||||||||||||||||||
&& (rhs.memberships.bits() & self.filter.bits()) != 0 | ||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
/// Check if interactions should be allowed based on the interaction memberships and filter. | ||||||||||||||||||||||||||
/// | ||||||||||||||||||||||||||
/// An interaction is allowed iff. the groups of `self` contain at least one bit set to 1 in common | ||||||||||||||||||||||||||
/// with the mask of `rhs`, **or** vice-versa. | ||||||||||||||||||||||||||
#[inline] | ||||||||||||||||||||||||||
pub const fn test_or(self, rhs: Self) -> bool { | ||||||||||||||||||||||||||
(self.memberships.bits() & rhs.filter.bits()) != 0 | ||||||||||||||||||||||||||
|| (rhs.memberships.bits() & self.filter.bits()) != 0 | ||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
/// Check if interactions should be allowed based on the interaction memberships and filter. | ||||||||||||||||||||||||||
/// | ||||||||||||||||||||||||||
/// See [`InteractionTestMode`] for more info. | ||||||||||||||||||||||||||
#[inline] | ||||||||||||||||||||||||||
pub const fn test(self, rhs: Self) -> bool { | ||||||||||||||||||||||||||
match self.test_mode { | ||||||||||||||||||||||||||
InteractionTestMode::AND => self.test_and(rhs), | ||||||||||||||||||||||||||
InteractionTestMode::OR => self.test_or(rhs), | ||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||
Comment on lines
+102
to
+107
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This will create some hard to predict behavior if one of the interaction groups is set to
Suggested change
This precedence rule should be explained in the |
||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
impl Default for InteractionGroups { | ||||||||||||||||||||||||||
fn default() -> Self { | ||||||||||||||||||||||||||
Self { | ||||||||||||||||||||||||||
memberships: Group::GROUP_1, | ||||||||||||||||||||||||||
filter: Group::ALL, | ||||||||||||||||||||||||||
test_mode: InteractionTestMode::AND, | ||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should it be
max(0.0)
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(outside of this PR's scope) @sebcrozet why does this function takes
u8
rather thanCoefficientCombineRule
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there is some use-case for this in godot but that would be worth clarifying by @Ughuuu.
I don’t think there is a particular reason for this.