简体   繁体   中英

three.js - ray intersection and sphere position

I've a scene with tube geometry and ray intersection is working fine. Upon ray intersection I am showing a small red color sphere and a tooltip next to the cursor. Please find the image without header:

没有标题的图像

Now if I add a header with div element, the ray intersection is working but the issue is there is a distance between red sphere, tooltip and a mouse cursor. Please find the image with header:

带有标题的图像

Please find below the code of header, tool-tip div, sphere and collision detection function:

Header:

<div style="margin-top:10px;margin-left:3%;height:100px;width:70%">
  <label style="color:#b0bb02;font-size:14pt">three.js</label>
  <label style="color:#f5f7f9;font-size:14pt;font-weight:bold">Tube Geometry</label><br><br>               
</div>

Tool-tip div:

textDiv = document.createElement( 'div' );          
            textDiv.style.position = 'absolute';
            textDiv.style.top = '50px';
            textDiv.style.margin = '8px';
            textDiv.style.border = '1px solid blue';
            textDiv.style.zIndex = '100';
            textDiv.style.background = '#ffffff';
            textDiv.style.display = 'block';
            container.appendChild( textDiv );

Sphere geometry:

dot = new THREE.Mesh ( new THREE.SphereGeometry( 1, 12, 1 ), new THREE.MeshBasicMaterial( { color: 0xff0000 } ) );

Collision detection:

var intersects;
        
        function detectCollision(event){
            
            var vector = new THREE.Vector3(( event.clientX / window.innerWidth ) * 2 - 1,- ( event.clientY / window.innerHeight ) * 2 + 1, 0.5 );
            
            /*var mouse_x =   ((event.pageX-event.target.offsetParent.offsetLeft) / renderer.domElement.width) * 2 - 1;
            var mouse_y = - ((event.pageY-event.target.offsetParent.offsetTop) / renderer.domElement.height) * 2 + 1;
            var vector = new THREE.Vector3(mouse_x, mouse_y, 0.5);*/
                
                projector.unprojectVector( vector, camera );
                var ray = new THREE.Raycaster( camera.position, vector.subSelf( camera.position ).normalize() );

                intersects = ray.intersectObjects( objects );                                   
                
                var pnt=0; var clickedMD = 0; var clickedDegree; var clickedTVD;
                
                if ( intersects.length > 0 ) {                  
                                                                            
                    dot.position.copy( intersects[0].point );
                    scene.add( dot );
                    
                    var fi = intersects[0].faceIndex;
                    pnt = Math.round(fi/11);                    
                    
                    clickedMD = pathObjColl[pnt].md;
                    clickedTVD = Math.round(pathObjColl[pnt].point.z);
                    clickedDegree = degrees[Math.round(fi%11)]; 
                    
                    // tooltip
                    var elem = document.getElementsByTagName("canvas");
                    var canvas = elem[0];
                    var x = event.pageX - canvas.offsetLeft ;
                    var y = event.pageY - canvas.offsetTop  ;
                    //console.log("X: "+x+" Y: "+y);
                    textDiv.style.top = y+"px";
                    textDiv.style.left = x+"px";                
                    textDiv.innerHTML = "&nbsp;Degree: "+clickedDegree+"<br/>&nbsp;MD: "+clickedMD+" ft<br/>&nbsp;TVD: "+clickedTVD+" ft";
                    if(textDiv.style.display == 'none'){
                        textDiv.style.display = 'block';    
                    }
                }
                
                else if(intersects.length == 0){
                    var textDivVis = textDiv.style.display;
                    console.log(textDivVis);
                    if(textDivVis == 'block'){
                        textDiv.style.display = 'none'; 
                    }
                    
                }
            
        }

demo on jsfiddle

Why there is a distance between the mouse cursor, sphere geometry and a too-tip if I add header ?

Is the textDiv positioned absolutely? Maybe the header just throws off the layout of the page, and the tooltip.. Try this:

textDiv.style.position = "absolute";

EDIT:

Well, in fact it's the header that needs to be absolutely positioned.. Otherwise it will move the canvas and your mouse position in HTML does not match mouse position in the webgl canvas.

Alternatively, if you don't want the header to be on top of canvas, you can take your container position into account when calculating mouse position. For the Vector:

       var vector = new THREE.Vector3( 
                ( (event.pageX - container.offsetLeft) / window.innerWidth ) * 2 - 1, 
                - ( (event.pageY - container.offsetTop) / window.innerHeight ) * 2 + 1, 
                0.5 );

For the tooltip:

                textDiv.style.top = (container.offsetTop + y)+"px";
                textDiv.style.left = (container.offsetLeft + x)+"px";       

Updated jsFiddle: http://jsfiddle.net/tje8y/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM