Mouse press down coordinates shifts to another location in 3D world

Hi,

I have learned from the lasso project(three-mesh-bvh - Geometry Collect Triangles) how to draw a line while the mouse press down, which is more efficient than what I implemented before! I used to create a 2D canvas put on top of a 3D canvas to complete this feature, but I think creating directly in the 3D scene is a better solution.

However, I encounter an issue, the issue is when I press down the mouse on a point on the 3D scene, the point shift to another place, which seems to project an issue or something wrong.

I put the code in the codepen

The red line is the position I draw a circle by mouse, but the project position is the yellow line

Here is my code, the onGeneCanvasPointmove function is collecting coordinates into selectionPoints array,

function onGeneCanvasPointmove(event) {

        var checkedVal = $(".gene_interactive:checked").val();

        if (checkedVal != "square" && checkedVal != "freehand") {
            return false;
        }

        if (geneScene.scene.children.length === 0) {
            return false;
        }

        if (isDown) {

            const ex = event.clientX;
            const ey = event.clientY;

            var domRect = geneScene.renderer.domElement.getBoundingClientRect();
            const nx = ((event.clientX - domRect.left) / (domRect.right - domRect.left)) * 2 - 1;
            const ny = -((event.clientY - domRect.top) / (domRect.bottom - domRect.top)) * 2 + 1;

          
                if (Math.abs(ex - prevX) >= 3 || Math.abs(ey - prevY) >= 3) {

                    const i = (selectionPoints.length / 3) - 1;
                    const i3 = i * 3;
                    let doReplace = false;
                    if (selectionPoints.length > 3) {

                        // prev segment direction
                        tempVec0.set(selectionPoints[i3 - 3], selectionPoints[i3 - 3 + 1]);
                        tempVec1.set(selectionPoints[i3], selectionPoints[i3 + 1]);
                        tempVec1.sub(tempVec0).normalize();

                        // this segment direction
                        tempVec0.set(selectionPoints[i3], selectionPoints[i3 + 1]);
                        tempVec2.set(nx, ny);
                        tempVec2.sub(tempVec0).normalize();

                        const dot = tempVec1.dot(tempVec2);
                        doReplace = dot > 0.99;
                    }

                    if (doReplace) {

                        selectionPoints[i3] = nx;
                        selectionPoints[i3 + 1] = ny;

                    } else {

                        selectionPoints.push(nx, ny, 0);

                    }

                    selectionShapeNeedsUpdate = true;
                    selectionShape.visible = true;

                    prevX = ex;
                    prevY = ey;

                    selectionNeedsUpdate = true;
                }
        }
    }

in render function, the shape will be updated

const ogLength = selectionPoints.length;
    selectionPoints.push(
        selectionPoints[0],
        selectionPoints[1],
        selectionPoints[2]
    );

    selectionShape.geometry.setAttribute(
        'position',
        new THREE.Float32BufferAttribute(selectionPoints, 3, false)
    );

    selectionPoints.length = ogLength;

    if (selectionNeedsUpdate) {

        selectionNeedsUpdate = false;

        if (selectionPoints.length > 0) {

            updateSelection();

        }

    }

My question is why the mouse press down location is different to the shape create location?
Hope someone could give me some tips.
Thanks!

Must disagree with you here. I suggest doing some benchmarking to find the more efferent method.

Tip: freeze the scene ( no camera transformation ) when creating the polygon,

1 Like