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