3d - js教程 - 将一个网格拖到另一个网格上,并将其限制在three.js边



three js教程 (1)

我必须创建一个像结构的房子,用户可以在墙上添加窗户。 我想的方法是首先为窗口创建一个单独的网格,用户可以将其拖动到所选网格的墙上,然后放在他们觉得合适的地方,但是放在同一个墙或同一个网格内。 之后,我将再次创建整个场景,但在房屋网格的墙上绘制窗口,而不是创建单独的窗口网格。

以下是在墙上看到窗户网格时的样子,

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

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

但不知道如何限制拖动,使窗户不能走出墙壁。

它是一个工作示例,我创建了可以拖动的构建网格和窗口网格 - 小提琴


你可以不使用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