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!