aframe
aframe copied to clipboard
Default of 1m for raycaster proximity to Line and Point is far too high
Description:
- A-Frame Version: 1.3.0
- Platform / Device: All
- Reproducible Code Snippet or URL:
https://climbing-productive-riddle.glitch.me/
source code: https://glitch.com/edit/#!/climbing-productive-riddle?path=border.js%3A29%3A4
- Raised a a result of an issue reported on A-Frame Slack channel.
The problem here is that the border lines are children of the squares, and get included in raycasting.
The default raycaster params set up the distance threshold for raycasting to points & lines to 1 unit.
That might makes sense in a THREE.js world, where units are undefined. But in the A-Frame world, where 1 unit is 1 meter, it's a pretty wild margin of error, which gives patently "wrong" behaviour for pretty much any raycasting against Lines or Points.
Rather than 1m, I'd suggest 1cm seems like a suitable default margin of error for A-Frame when raycasting to lines. Easy fix to override the default values of 1 with values of 0.01.
I was going to suggest making a change as a PR, but there's a couple of complicating factors:
-
Risk of making a non-backcompatible change that breaks existing A-Frame apps. I can't imagine an app for which the default threshold of 1m would make sense, but they might exist. Or the app author may have compensated for this using scale - see below.
-
I'm a little unclear how scale works. If 1 unit is 1m, that's definitely not a good default for raycasting. But suppose someone is raycasting against a group of objects that are collectively scaled down by a factor of 100 or so (e.g. a diorama)
There is some logic in THREE.Line and THREE.Points that uses local object3D scale to compute a localThreshold, which is used in assessing proximity. However this seems to only account for the object3D's local scale, I don't see how it accounts for world scale. Maybe it doesn't, in which case reducing the threshold by a factor of 100 might cause problems.
I may be missing something, but it looks to me like a bug in THREE.js, where really this should be considering world scale, rather than local scale in computing an appropriate threshold.
If THREE.js got scale correct, I think I'd be comfortable recommending a non-back compatible change to default values of 0.01. As it is, with concerns that THREE.js might end up computing scale incorrectly, I think there is some appreciable risk of breaking existing function by changing these defaults.
Next step, then, might be some testing with THREE.js to see whether threshold scaling is actually correct for Lines and Points in deep Object3D hierarchies, with multiple levels of scaling.
-
If there is a THREE.js bug, then we can fix that, then make the change to the default values in A-Frame.
-
If there is no such THREE.js bug (i.e. scaling is correctly applied to Line/Point raycast thresholds in all cases, then I think we could go just go ahead with an A-Frame fix to change default values.
I came across this issue again in a project I was working on, and built a component that addresses it.
https://diarmidmackenzie.github.io/aframe-examples/component-usage/raycaster-thresholds.html
<script src="https://cdn.jsdelivr.net/gh/diarmidmackenzie/aframe-examples/components/raycaster-thresholds.min.js"></script>
I think it might be worth incorporating this function into the core A-Frame raycaster component.
Also, contrary to what I said above, I'm not inclined to investigate possible THREE.js bugs. Given that A-Frame is AIUI committed to semantic versioning, there should be no API changes outside of an upgrade to v2, so the default value should stay at 1, no matter whether there are bugs in THREE.js.
Making it easy to change the thresholds on the raycaster component by adding threshold config would be the best solution to offer IMO.
In the meantime, my external raycaster-thresholds
component provides the same function, albeit with less convenience, given it's not part of core A-Frame.