-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Add layer check between Camera and Element when testing for input. #4210
Conversation
src/input/element-input.js
Outdated
@@ -948,6 +948,11 @@ class ElementInput { | |||
for (let i = 0, len = this._elements.length; i < len; i++) { | |||
const element = this._elements[i]; | |||
|
|||
// check if any of the layers this element renders to is being rendered by the camera | |||
if (!element.layers.some(v => camera.layers.indexOf(v) !== -1)) { |
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.
This is definitely not performant to run for every element, and doing many-to-many search.
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.
Yes, I totally agree :/ To be honest I've been trying to figure out a better solution but couldn't find anything. I'm sending the PR to see if anyone has any ideas.
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.
the easiest way would be to add camera.layers to a Set. Either inside the Camera class .. when set layers
is called, it copies data to an array .. it should also build a Set (few classes in the engine do this already, for example in LayerComposition). Then camera.layers.indexOf(v)
would be camera.layersSet.has(v)
or similar.
You could also have global const _tempSet = new Set();
and populate it inside _getTargetElement
function (outside of the loop) - I assume this is called once a frame only?
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.
that you still only bring O(n^2) to O(n) .. going to O(1) would require bitflags on both side .. which would not be super easy. But perhaps O(n) here is enough, especially since the n is usually pretty small here.
Given this going to be a more expensive for a less common use case, can we put this on a toggle? Eg on the screen component |
I'm not sure that is required. The solution using a Set is very cheap. And considering most elements are only on a single layer, this is an O(1) solution. |
6da6ee5
to
5474d9b
Compare
I agree with Martin here - I believe the |
Fixes #4180
Add layer check between Camera and Element when testing for input, with performance-friendly implementation using a new
layersSet
property in Camera.Tested against https://launch.playcanvas.com/1383836?debug=true and works as expected.
I confirm I have read the contributing guidelines and signed the Contributor License Agreement.