0

In my project, using Three.JS I have implemented the functionality where I want my camera to zoom to the cursor position. Below is the function for that. In this function, I am using a factor as static value 5.

              onWheelMove = (event: WheelEvent): void => {

              let rect: ClientRect = this.canvas.getBoundingClientRect();

              var factor = 5;

              this.mousePos.x = (event.clientX - rect.left) / this.renderer.domElement.width * 2 - 1;
              this.mousePos.y = -(event.clientY - rect.top) / this.renderer.domElement.height * 2 + 1;

              console.log("X-->", this.mousePos.x);
              console.log("Y-->", this.mousePos.y);
              var vector = new THREE.Vector3(this.mousePos.x, this.mousePos.y, 0.5);
              vector.unproject(this.camera);
              console.log("mouse wheel vector -- >", vector);
              vector.sub(this.camera.position);

              console.log("vector.setLength(factor)-- > ", vector.setLength(factor));
              if (event.deltaY < 0) {
                 this.camera.position.addVectors(this.camera.position, vector);
              } else {
                 this.camera.position.subVectors(this.camera.position, vector);
              }

              this.camera.updateMatrixWorld(true);
              this.enableRender();
              this.render(true);
          }

model

Now Look at the above picture, this is my project viewer and the camera at initialization time is not perpendicular to the model. at this point, if I am keeping my cursor exactly on axis-helper and do mouse wheel up/down, then I am getting below the value of setLength(vector).

vector.setLength(factor)-- > Vector3 {x: 1.6930115334358085, y: -3.3042632885205743, z: -3.348963431838058} -3.30 instead of 5.

Now look at another picture below

camera perpendicular to model

Here, you can see that I moved the camera on top view, now when I am doing mouse wheel up/down, then below value is coming vector.setLength(factor)-- > Vector3 {x: 0.02806398289696144, y: -4.998806591956658, z: -0.10557020921938588}

see -4.99 which is closer to 5, that I am setting as a factor. but in this case also, if I am keeping my cursor somewhere else, let say the top right corner of the canvas and do mouse wheel up/down, the value gets changed

vector.setLength(factor)-- > Vector3 {x: -1.724124575016607, y: -4.527894564140576, z: -1.2351377517710418}

-.4.52

now all these values of 3.30, -4.52 which are not exactly 5, messing up my other function. look below

private _setPivotPointOnMouseHit(mouseEvent: MouseEvent, shouldRerender: boolean = true): void {
        this._setRaycasterFromMouse(mouseEvent);

        let rect: ClientRect = this.canvas.getBoundingClientRect();

        let intersects: THREE.Intersection[] = this.octree.raycast(this.raycaster);
        let minTargetToCameraDistanceAllowed = 10;

        intersects.sort(function (a: THREE.Intersection, b: THREE.Intersection): number {
            return a.distance - b.distance;
        });

        if (!intersects || intersects.length === 0) {

            var distance = new THREE.Vector3().subVectors(this.camera.position, this.controls.target).length();

            console.log("camera position-->", this.camera.position);
            console.log("this.controls.target.distanceTo(this.camera.position)",this.controls.target.distanceTo(this.camera.position));
            var targetToCameraDistance = Math.max(minTargetToCameraDistanceAllowed,this.controls.target.distanceTo(this.camera.position));

            console.log("target to camera dstce-->",targetToCameraDistance);
            var vc2 = new THREE.Vector3();
            this.camera.getWorldDirection(vc2);
            var newTarget = vc2.setLength( targetToCameraDistance ).add(this.camera.position);
            console.log("New Target-->",newTarget);

            this.controls.target = newTarget;
            this.controls.update();
            this.camera.updateProjectionMatrix();

            return;
        }

        this._setPivotPoint(intersects[0].point);

        if(shouldRerender) {
            this.render();
        }
    }

In the above function, I am trying to set the orbit controls target even if intersects value is 0. if intersection happening, then everything is working, but if intersection not happening, then my controls target in setting in the middle of object area, because of mismatch between factor 5 and length of vector-based on the cursor position. if I check camera distance in above function, I clearly see 5 is getting add/subtract from an old distance but if I check the camera position, then it is variable based on cursor position and camera look At an angle.

It has something to do with the angle between camera and mouse cursor, but I am not able to understand what.? How can I make sure that no matter the angle/position/cursor, it should always add/subtract factor 5 to camera-target distance and camera position.?

gman
  • 100,619
  • 31
  • 269
  • 393
SIM
  • 73
  • 1
  • 14
  • Also, 'onWheelMove = (event: WheelEvent): void => {' What language is this? coffee? – Ethan Hermsey Jan 23 '20 at 19:51
  • intens question ;) Just thinking out loud here.. What if you would combine the two functions.. in the mousewheel event>use the mousePos to move the pivot to the zoomin location, then just let the orbitcontrol handle the zoom? This is the only thing these function are meant to be controlling right? Or is the camera not attached to the orbitcontrol all the time? – Ethan Hermsey Jan 23 '20 at 19:57
  • That is what I am trying to do, with the click of mouse button, i want the pivot to move either at the mouse click location or somewhere near mouse click location. Currently when I am clicking, after zooming to certain area, pivot is coming near mouse click but not exactly within model range, it is going beyond that. Because with every wheel up down, i am adding 5 to it, irrespective of camera angle towards mouse cursor.. So sometimes, the length is coming only 3.3 which is getting add to camera pos, bt my distance is getting add/subtract by 5, with each wheel movement. – SIM Jan 23 '20 at 20:03
  • This mismatch, 3.3 and 5, sometimes 4.5 and 5..is what moving the pivot ahead. It is typescript. Can't make it in a single function, as it is used by other apis too and by front end also. Let say I want to zoom a particular area and camera is not perpendicular to object, on mouse click, i want to set pivot there or orbit target there, how can i do that – SIM Jan 23 '20 at 20:05
  • I've tried my idea. It doesn't work. https://jsfiddle.net/EthanHermsey/x5p6gswu/49/ The left clicking to move the orbit does, but zooming towards the mousecursor does not look good (because the view changes everytime, the mousecursor points to a different place). I'm still a little confused about why you would zoom the camera manually when the orbit does it automatically. In this case, would it not be easier to customize the code or build your own controls? It's not that hard.. – Ethan Hermsey Jan 23 '20 at 20:29
  • The reason why the vector doesn't come out as 5 is that the length (of all the x,y,z components) is set to 5. Since the vector is angled (if it was a vec3(0, 0, 1) it would turn into vec3(0, 0, 5) none of the components will turn to 5, but the overall length is. Do you get what i mean? :s – Ethan Hermsey Jan 23 '20 at 20:31
  • Actually, it was automatically via orbit controls earlier, but requirement was to move it where the cursor is, like many modeling tools in BIM industry. So I had to write my own wheel action, because orbit controls was zooming always in the center of canvas, irrespective of where ever I set the pivot axis.. Something someone already did in the project. Its kind of huge. So I thought How difficult it would be to adjust camera following the cursor position. So I wrote custom wheel action,then I found the problm u described, as soon as I click, my camera jumps towards pivot. – SIM Jan 23 '20 at 20:58
  • So I tried setting pivot near to mouse on mouse click. Now it stopped the jumping of camera, but only that mismatch is messing me, as pivot is getting set somewhere down the model and if user tries to rotate, it rotate around that miscalculated pivot, i am trying to bring it inside the object's range – SIM Jan 23 '20 at 21:01
  • https://stackoverflow.com/questions/35657231/threejs-orbit-controls-set-target-without-lookat That first anwer maybe? – Ethan Hermsey Jan 23 '20 at 22:04
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/206577/discussion-between-sim-and-ethan-hermsey). – SIM Jan 24 '20 at 11:17

0 Answers0