3

I wrote a simple web page displaying a 3D bone and using Three.js raycasting to draw dots and lines on it and it worked perfectly well. result of using raycast on full screen web page

But when I ported it to another web page having multiple windows, the process did not work.

I followed the instructions from fiddle http://jsfiddle.net/cn7ecoaa/ but still failed.

Here is the CSS:

.column2  {
    float: right;
    width: 80%;
    position: static;
}

#w3-container {
    width: 1522px;
    height: 1001px;
    position: static;
}

I loaded the model and examined it and it certainly contains mesh and buffer geometry: result of console.log after loading the 3D model

Here is the loader code :

gltfLoader.load (   
                    inputModel,
                
                    function(gltf)
                    {
                        scene.add(gltf.scene);
                        model = gltf.scene;
                        mesh = gltf.scene.children[0];

                        mesh.name = "tibia_glTF_01";
                        
                        model.traverse
                        ( function ( child ) 
                            {
                                
                                if ( child.isMesh && child.geometry.isBufferGeometry) 
                                { 
                                    const material = new THREE.MeshPhongMaterial(  {color:0x3c3c3c, emissive: 0x000000 } );
                                    child.material = material;
                                    const bg = child.geometry;
                                    console.log("Do not change geometry.");
                                    
                                }
                            }  
                        );

                        getItem();  // Refresh the item list to be displayed

                        objects.push( mesh );
                        
                    });

Here is the code for handling the onmousedown event :

function onMouseDown( event ) {

    if ( !DRAWLINE ) return;

    var raycaster = new THREE.Raycaster();

    event.preventDefault();

    mouse.x = (( event.clientX - renderer.domElement.offsetLeft) / renderer.domElement.clientWidth ) * 2 - 1;
    mouse.y = - (( event.clientY - renderer.domElement.offsetTop) / renderer.domElement.clientHeight ) * 2 + 1;

    console.log("mouse.x", mouse.x, "mouse.y", mouse.y);

    console.log("Objects", objects);

    raycaster.setFromCamera(mouse, camera);

    var intersects = raycaster.intersectObjects( objects );

    if ( intersects.length > 0 ) {

        alert("HIT!");

        dot.visible = true;

        // Copy the intersection points to be used in functions addPoint()
        mouse.copy( intersects[0].point );

        intersects.length = 0; // reset the variable
    
        addPoint();

    } else {

        console.log( "<<NO Intersection!!>>" );

    }

}

No matter what combinations I have used to cater for the offset, the result of raycasting is still "<<NO Intersection!!>>".

Any idea on how to fix this would be much appreciated! Thanks for your help!

Ringo Work
  • 33
  • 5

1 Answers1

2

Try computing your mouse coordinates like so:

const rect = renderer.domElement.getBoundingClientRect();
mouse.x = ( ( event.clientX - rect.left ) / ( rect. right - rect.left ) ) * 2 - 1;
mouse.y = - ( ( event.clientY - rect.top ) / ( rect.bottom - rect.top) ) * 2 + 1;
Mugen87
  • 28,829
  • 4
  • 27
  • 50
  • Thanks for your prompt reply Mugen87. I know that this is an old question and ppl have asked numerous times but to my surprise, I can't figure out where the problem is, nor can I resolve it using your suggestion. I wonder if there is something to do with the 3D model being geometry or buffer geometry? Although I have tried both. Thanks a lot anyway! Ringo – Ringo Work Nov 16 '21 at 04:56
  • The layout of the web page is based on "multiple viewport" of Three.js demo : https://threejs.org/examples/webgl_multiple_views.html Would it be something to do with this that makes the raycasting failed? – Ringo Work Nov 16 '21 at 06:05
  • Um, that's hard to tell. It's probably best if you demonstrate the issue somehow with a live example (like a fiddle). – Mugen87 Nov 16 '21 at 08:30
  • I see, it makes sense of doing so. But since the source code is so huge and entangled, I don't think it is easy to make a fiddle demo. Let me try to clean up first. Thanks. – Ringo Work Nov 16 '21 at 08:38
  • Maybe you can use the code from the `webgl_multiple_views` for the live demo. Meaning modifying it so the issue occurs. If you manage to isolate the issue in that way, it should be easier to investigate and potentially fix it. – Mugen87 Nov 16 '21 at 08:46
  • Thanks and I will try to investigate. – Ringo Work Nov 16 '21 at 14:16
  • Finally, I had to specify which sub-window to response to the raycasting. For example, if the action is done on the 2nd window view port, then I need to add these lines to the onmousedown event listener : var view = views[3]; var camera = view.camera; That's all is needed. Thanks. – Ringo Work Dec 07 '21 at 06:53