react-three-fiber icon indicating copy to clipboard operation
react-three-fiber copied to clipboard

onPointerOver only listens when mouse moves

Open gomes042 opened this issue 2 years ago • 6 comments

If the cursor is stopped and an element enters the contact area, the event is only called when the mouse moves. No "last cursor position" is recorded and there is no recalculation during frames.

gomes042 avatar Apr 30 '22 23:04 gomes042

that's expected behaviour. i think even the dom operates that way. but either way it would cost too much to run raycasting on every frame. if you want that you can do it in userland by calling onpointermove inside useFrame, the handlers are all in the state object, state.events.handlers i believe it was.

drcmda avatar May 01 '22 10:05 drcmda

There are ways to solve 'this problem' without webworkers or alternatives like that, it's not necessary for all objects in a scene to be recalculated within raycasting, since everything outside the camera's view area never listens to "onPointerOver" becoming an impossible scenario, elements that don't call the same property in their declaration also never need to be calculated.

that's expected behaviour. i think even the dom operates that way. but either way it would cost too much to run raycasting on every frame. if you want that you can do it in userland by calling onpointermove inside useFrame, the handlers are all in the state object, state.events.handlers i believe it was.

gomes042 avatar May 01 '22 22:05 gomes042

R3F only raycasts against interactable objects that have handlers registered, so I'm not sure much more can be done there as far as optimizing events' filtering. Three's also intelligent enough to not recalculate bounding boxes/spheres needlessly. I would still advise doing this in a web worker since this is otherwise too slow to maintain a stable framerate.

CodyJasonBennett avatar May 01 '22 23:05 CodyJasonBennett

At first, I couldn't say a smart way to do this, I think the solution doesn't need to depend on an implementation with webworkers (of course it would be ideal but it's good to think about cases where this feature is not available). Speaking of use cases, I really see this as a problem, because it's not interesting for the person to have to implement their own handlers if the library already has it as a resource and apparently you also have this perspective. Of course, tests need to be done, but I really don't rule out a smart solution for this, considering that if you move the mouse quickly, the FPS doesn't go away even with several calls per second. The question is figuring out the factor that should tell when a recalculation needs to be done.

gomes042 avatar May 02 '22 11:05 gomes042

An initial solution could be to provide some kind of hook that would force the raycast to be recalculated. So it's up to the user to handle this in their Event Loop/Physics Loop, although I think this should be automatic someway

gomes042 avatar May 02 '22 11:05 gomes042

We're only as fast as threejs here with actual raycasting overhead, but a faster solution could use something like three-mesh-bvh.

CodyJasonBennett avatar May 09 '22 14:05 CodyJasonBennett

Currently, we can't support this due to the performance ramifications of three's built-in raycaster. I'd consider this as a feature request if we do use https://github.com/gkjohnson/three-mesh-bvh to partition the scene to where this is feasible.

CodyJasonBennett avatar Sep 03 '22 01:09 CodyJasonBennett