Skip to content
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

Merged
merged 2 commits into from
Aug 19, 2022

Conversation

jpauloruschel
Copy link
Contributor

@jpauloruschel jpauloruschel commented Apr 22, 2022

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.

@jpauloruschel jpauloruschel added bug area: ui UI related issue labels Apr 22, 2022
@jpauloruschel jpauloruschel requested a review from a team April 22, 2022 15:51
@jpauloruschel jpauloruschel self-assigned this Apr 22, 2022
@@ -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)) {
Copy link
Contributor

@Maksims Maksims Apr 22, 2022

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.

Copy link
Contributor Author

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.

Copy link
Contributor

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?

Copy link
Contributor

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.

@jpauloruschel jpauloruschel added the area: input Input related issue label Apr 22, 2022
@yaustar
Copy link
Contributor

yaustar commented Apr 28, 2022

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

@mvaligursky
Copy link
Contributor

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.

@jpauloruschel jpauloruschel force-pushed the jpaulo-fix-cameras-render-input branch from 6da6ee5 to 5474d9b Compare August 17, 2022 12:21
@jpauloruschel
Copy link
Contributor Author

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.

I agree with Martin here - I believe the Set approach is more than fast enough.

@jpauloruschel jpauloruschel merged commit f6f1461 into main Aug 19, 2022
@jpauloruschel jpauloruschel deleted the jpaulo-fix-cameras-render-input branch August 19, 2022 15:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: input Input related issue area: ui UI related issue bug
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Issue with two cameras and different render layers where events are fired through (culling)
4 participants