简体   繁体   中英

How to draw a geometry shape exactly where mouse is clicked in ThreeJS

I am trying to draw a circle exactly where mouse is clicked, but circle is drawn not at exact position. Please let me know what needs to be corrected in the code:

            var camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 10000 );
            camera.position.set( 0, 0, 1000 );


            document.addEventListener( 'mousedown', onDocumentMouseDown, false );

            function onDocumentMouseDown( event ) {
                event.preventDefault();


                if( event.which == 1) { // left mouse click

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

                    var x = event.clientX; // x coordinate of a mouse pointer
                    var y = event.clientY; // y coordinate of a mouse pointer
                    var rect = event.target.getBoundingClientRect();

                    x = ((x - rect.left) - window.innerWidth/2)/(window.innerWidth/2);
                    y = (window.innerHeight/2 - (y - rect.top))/(window.innerHeight/2);

                    var geometry = new THREE.CircleGeometry( 20, 32 );
                    var material = new THREE.MeshBasicMaterial( { color: 0x65A8FF } );
                    circle = new THREE.Mesh( geometry, material );

                    //circle.position.x = x*window.innerWidth*1.23;
                    //circle.position.y = y*765; 

                    circle.position.x = x*window.innerWidth;
                    circle.position.y = y*window.innerHeight;

                    scene.add( circle );
                }
            }

The problem with your approach is that it's assuming 3D xy coordinates are connected to pixel coordinates without taking the camera's perspective or depth into account. With a perspective camera, the deeper the point goes, the greater its x, y coords will be. You need to set a depth (z) for the points to stop at. Additionally, if your camera moves or rotates, your X, Y coordinates will not work.

I recommend you use a THREE.Raycaster , which performs all those camera projection calculations for you (the docs have an example of its usage at the top of the page). You can see that approach in action in this example .

The way it works is:

  1. You create a plane for the raycaster to hit (this is your depth).
  2. Create a raycast with Raycaster.setFromCamera()
  3. Read back the position where the ray hits the plane.
  4. Use this position to create your geometry.

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