Orbit Controls with constraint set to "lock" prevents panning feature

Hey there,
the orbit controls are already very handy to create a scene like the hotspot sample. But when I create an example case for internal testing, I still get some difficulties:

To orbit around a scene it works all well. I use the “Change Transform on Click” Comp to move camera and lookAtTarget to another view (position/focus). To get this working I have to use the “lock” setting on the “Look At Constraint” Comp. Without it, panning the camera would offset the view in a bad way.

Now the left mouse button orbits the view, and the right mouse button (or two finger touch) also kind of, but slowly. It seem it still pans, but because it looks at same focus, it does not work anymore as expected.

Maybe it’s more convenient, if we could bind the lookAt-target to the camera while panning (or apply the same translation to it), so that the pan again would work.

What do you think?

p.s.: I’m impressed, how fast I could setup an interactive scene with needles. Good work. Still struggling to understand so many web, typescript, compiling, npm, node, stuff… which gives me headaches coming from the original engine workflow. Questions here already helped me and also documentation, but there’s a lot to rethink/relearn.

Original Post on Discord

by user 539536674582036491

Hey :wave: from what i understand, you are trying to have this kind of functionality, correct? https://engine.needle.tools/samples/spatial-audio/

If so, you should be able to use the sample directly in your project.

p.s.: I'm impressed, how fast I could setup an interactive scene with needles. Happy to hear that :slightly_smiling_face:

Thank you!
This was good input. I had not expected, to find the answer in this sample, and so I also had create my first typescript :face_with_monocle: scripts… I feel newbie again.

OrbitControls.setTarget() and
OrbitControls.setCameraTargetPosition(…);

…did the trick for me, sending cam and focus to other positions while lock is enabled. This lead me to another problem, which is maybe also easy to solve: when the cam tweens to the new position, every user input stops the tween. How can I temporarily disable the input from OrbitController… I disabled it, but then it is also not tweening. Disable “enableRotation” did also not helped.

by user 539536674582036491

Happy to hear! :cactus:

I think the simplest is to just set the
EnableRotation, EnableKeys, EnableZoom, EnablePan, MiddleClickToFocus and DoubleClickToFocus all to false and that should disable the camera’s user input.

Sadly this does not work. When I look in onBeforeRender() I can also see, that the lerping to targets is always interrupted due user input.

by user 539536674582036491

With this in mind, there comes a more generic question in mind: how shall I handle such problems?

Try to solve it on my own?
Or discuss in this question section?

Due all these comps are organized in packages/cache, I already noticed, that changing them is not possible. I asume, I could copy them and modify and create my own version of it, but I’m also not sure, if this is feature proof solution for me…

In long term, I don’t want to annoy people with my small thoughts about optimizations, but I do user interactions too long not to have special wishes. On the other hand, it could be interesting for you as well to be proven on use cases.

by user 539536674582036491

It’s good to discuss it here! Often times those questions are very valid usecases and things we want to fix/improve in the components if possible (not always but there’s always a solution :slightly_smiling_face: )

About the user input: that’s a good point and probably a case of “adding an option for it” :slightly_smiling_face:

What you can always do to try or iterate/test is to copy the component and modify. We also have a couple of ways to adjust behaviour of existing components (e.g. with the @prefix decorator which can be used to override what a function does)

import { Behaviour, serializable } from "@needle-tools/engine";

@serializable()
orbitControls?: OrbitControls;

test() {
    if(!this.orbitControls) return;

    // disable input
    this.orbitControls.controls.stopListenToKeyEvents();
    // enable input
    this.orbitControls.controls.listenToKeyEvents(window.document.body);
}

It’s possible to temporarely modify them as well but you have to change the code in the lib folder of the needle engine package for example (the js classes are used by default)

To stop reacting to input, you can try the API on the controls property, which is the underlaying camera controller.

I tried this, but it seem not to work.
Input was possible after “stopListen” end if called again it throws: “Uncaught TypeError: Cannot read properties of null (reading ‘removeEventListener’)” - which is maybe kind of logic, but because I could still rotate the cam after stopping it may not work or I did something false.

by user 539536674582036491

If you think it’s helpful, I can also upload my scene to our server send you the link - then we now, what context we’re talking.

by user 539536674582036491

Ok :+1: you can use glitch as well

Ah, i see now. I was under the assumption the view transitioning was done in the Three’s OrbitControls.

Indeed any changes to the underlaying orbit controls do not change the behavior of the transitioning and how it is canceled.

Here’s my sandbox :slightly_smiling_face: - Minimal
If user enters a POI area like the pictures and zoom out, he should go to home view. Kind of works, but often interrupted, from mouswheel, etc. In future I try the same, when “zooming” to a POI - so that’s auto sets the lookAT. Also animation will be interesting to play with. As far until now, I’m happy with the progress. And also nice, that feedback here’s so fast…

by user 539536674582036491

I now have some family-weekend-stuff to do… but already exited, to further work on the scene. And read the docs :wink:

by user 539536674582036491

Very lovely scene :+1: