Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Drag a mesh over another and limit it within the sides three.js

I have to create a house like structure where user will be able to add windows on wall. The approach I am thinking is to first create a separate mesh for window which user can drag over the selected wall of the house mesh, and drops where they feel it suitable, but within the same wall or same side of the house mesh. After that I will create the whole scene again but draw the window in the wall of the house mesh instead of creating a separate window mesh.

Following is what it will look like when a window mesh is seen over a wall- window over wall

I am able to drag the window over wall using the DragControls.

dragControls = new THREE.DragControls( objects, camera, renderer.domElement );

but don't know how to limit the dragging so that window cannot go outside of the wall.

Its a working sample where I have created building mesh and window mesh which can be dragged - fiddle.

like image 654
Deeps Avatar asked Nov 08 '22 16:11

Deeps


1 Answers

You can do it without THREE.DragControls(). Just check, if the ray of your raycaster is intersecting the wall/building and, if it is, set window's position at the point of intersection.

There's a rough solution, which can be just the starting point for your creativity:

var controls = new THREE.OrbitControls(camera, renderer.domElement);

var building = new THREE.Mesh(...); // wall/building
var _window = new THREE.Mesh(...);  // window

var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
var intersects;
var normalMatrix = new THREE.Matrix3();
var worldNormal = new THREE.Vector3();
var lookAtVector = new THREE.Vector3();
var dragging = false;

window.addEventListener("mousemove", onMouseMove, false);
window.addEventListener("mousedown", onMouseDown, false);
window.addEventListener("mouseup", onMouseUp, false);

function onMouseDown(event) {
    if (intersects.length > 0) {
        controls.enableRotate = false;
        dragging = true;
    }
}

function onMouseUp(event) {
    controls.enableRotate = true;
    dragging = false;
}

function onMouseMove(event) {
    mouse.set((event.clientX / window.innerWidth) * 2 - 1, -(event.clientY / window.innerHeight) * 2 + 1);
    raycaster.setFromCamera(mouse, camera);
    intersects = raycaster.intersectObjects([building]);

    if (intersects.length == 0 || !dragging) return;

    normalMatrix.getNormalMatrix(intersects[0].object.matrixWorld);
    worldNormal.copy(intersects[0].face.normal).applyMatrix3(normalMatrix).normalize();
    _window.position.copy(intersects[0].point);
    _window.lookAt(lookAtVector.copy(intersects[0].point).add(worldNormal));
}

jsfiddle example r87

like image 191
prisoner849 Avatar answered Nov 15 '22 05:11

prisoner849