0
votes

I'm using the raycaster function to get the coordinates of portions of a texture as a preliminary to creating areas that will link to other portions of my website. The model I'm using is hollow and I'm raycasting to the intersection with the skin of the model from a point on the interior. I've used the standard technique suggested here and elsewhere to determine the coordinates in 3d space from mouse position:

        //1. sets the mouse position with a coordinate system where the center
        //   of the screen is the origin
        mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
        mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
        
        console.log("mouse position: (" + mouse.x + ", "+ mouse.y + ")");

        //2. set the picking ray from the camera position and mouse coordinates
        raycaster.setFromCamera( mouse, camera );    

        //3. compute intersections
        var intersects = raycaster.intersectObjects( scene.children, true );
        var intersect = null;
        var point = null;

        //console.log(intersects);

        for ( var i = 0; i < intersects.length; i++ ) {
            console.log(intersects[i]);
            if (i = intersects.length - 1) {
            intersect = intersects[ i ];
            point =  intersect[ "point" ];
            }

This works, but I'm getting inconsistent results if the camera position changes. My assumption right now is that this is because the mouse coordinates are generated from the center of the screen and that center has changed since I've moved the camera position. I know that getWorldPosition should stay consistent regardless of camera movement, but trying to call point.getWorldPosition returns "undefined" as a result. Is my thinking about why my results are inconsistent correct, and if so and I'm right that getWorldPosition is what I'm looking for how do I go about calling it so I can get the proper xyz coordinates for my intersect?

EDITED TO ADD: When I target what should be the same point (or close to) on the screen I get very different results.

For example, this is my model (and forgive the janky code under the hood -- I'm still working on it):

http://www.minorworksoflydgate.net/Model/three/examples/clopton_chapel_dev.html

Hitting the upper left corner of the first panel of writing on the opposite wall (so the spot marked with the x in the picture) gets these results (you can capture them within that model by hitting C, escaping out of the pointerlock, and viewing in the console) with the camera at 0,0,0:

x: -0.1947601252025508, ​ y: 0.15833788110908806, ​ z: -0.1643094916216681

enter image description here

If I move in the space (so with a camera position of x: -6.140427450769398, y: 1.9021520960972597e-14, z: -0.30737391540643844) I get the following results for that same spot (as shown in the second picture):

x: -6.229400824609087, ​ y: 0.20157559303778091, ​ z: -0.5109691487471469

enter image description here

My understanding is that if these are the world coordinates for the intersect point they should stay relatively similar, but that x coordinate is much different. Which makes sense since that's the axis the camera moves on, but shouldn't it not make a difference for the point of intersection?

2
What are the inconsistent results you're getting? I've used raycasters lots of time while the camera is moving, without any problems. The point you're getting should already be in world coordinates, so there would be no need to transform it into world again.Marquizzo
I put some further explanation, some pictures, and the link to my current dev model in the original post.medievalmatt
Is this line doing what you expect: if (i = intersects.length - 1) {. As it is it will set i to the last element in the array which seems odd to me and ultimately give you the last intersection rather than the first, closest intersection which is likely what you expect.Garrett Johnson

2 Answers

1
votes

My comment will not be related to the camera but I had also an issue about the raycaster and calculating the position of the mouse is more accurate with the following way.

const rect = renderer.domElement.getBoundingClientRect();
mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;
mouse.y = - ((event.clientY - rect.top) / rect.height) * 2 + 1;
0
votes

So the trick to this when there's no mouse available due to a pointer lock is to use the direction of the ray created by the object controls. It's actually pretty simple, but not really out there.

        var ray_direction = new THREE.Vector3();
        var ray = new THREE.Raycaster(); // create once and reuse

        controls.getDirection( ray_direction );
        ray.set( controls.getObject().position, ray_direction );