代码之家  ›  专栏  ›  技术社区  ›  Deeps

将网格拖动到另一个网格上,并将其限制在三条边内。js公司

  •  5
  • Deeps  · 技术社区  · 7 年前

    我必须创建一个像房子一样的结构,用户可以在墙上加窗。我正在考虑的方法是首先为窗口创建一个单独的网格,用户可以将其拖动到房屋网格的选定墙上,并将其放置在他们认为合适的位置,但在房屋网格的同一面墙或同一侧。之后,我将再次创建整个场景,但在房屋网格的墙上绘制窗户,而不是创建单独的窗户网格。

    window over wall

    我可以使用DragControl将窗口拖动到墙上。

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

    但不知道如何限制拖动,使窗口无法跳出墙外。

    这是一个工作示例,我在其中创建了可以拖动的建筑网格和窗口网格- fiddle .

    1 回复  |  直到 7 年前
        1
  •  1
  •   upe    2 年前

    你可以不用 THREE.DragControls() . 只需检查光线投射器的光线是否与墙/建筑相交,如果相交,请将窗口的位置设置在相交点。

    有一个粗略的解决方案,可以作为你创造力的起点:

    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 示例r87