我有一个我创建的3D房间和我房间的架子,我可以移动。 我想让我房间里的所有物品都留在我的房间里,用户不应该把任何物品拖出来。
我尝试了多种方法使其工作,但我没有做得很好。 现在架子有点走出房间,一旦它出来我就不能再移动它了。单击鼠标时我仍然可以拖动它。 我希望有一个人可以帮助我。我一直在努力解决这个话题,我的大脑才开始放弃:)
目前我的代码看起来像这样:
鼠标移动:
let bb = this.selectedHelper.geometry.boundingBox;
let originPoint = this.selected.position.clone();
originPoint.y = bb.getSize().y / 2;
originPoint.z += bb.getSize().z / 2;
this.raycasterLeft.set(originPoint, new THREE.Vector3(-1, 0, 0));
this.raycasterRight.set(new THREE.Vector3(originPoint.x + bb.getSize().x, originPoint.y, originPoint.z), new THREE.Vector3(1, 0, 0));
this.raycasterFront.set(new THREE.Vector3(originPoint.x + bb.getSize().x / 2, originPoint.y, originPoint.z + bb.getSize().z / 2), new THREE.Vector3(0, 0, 1));
this.raycasterBack.set(new THREE.Vector3(originPoint.x + bb.getSize().x / 2, originPoint.y, originPoint.z - bb.getSize().z / 2), new THREE.Vector3(0, 0, -1));
this.intersectionLeft = this.raycasterLeft.intersectObjects(this.walls, true);
this.intersectionRight = this.raycasterRight.intersectObjects(this.walls, true);
this.intersectionFront = this.raycasterFront.intersectObjects(this.walls, true);
this.intersectionBack = this.raycasterBack.intersectObjects(this.walls, true);
if (this.oktomove) {
this.selected.position.x = this.intersection.sub(this.offsetControls).x;
this.selected.position.z = this.intersection.z;
if (this.selected.name != "door" && this.selected.name != "regal") this.selected.position.y = this.intersection.y;
else { this.selected.position.y = 0; }
}
if (this.intersectionLeft.length > 0
&& this.intersectionRight.length > 0
&& this.intersectionFront.length > 0
&& this.intersectionBack.length > 0) {
if (this.intersectionLeft[0].distance >= 10
|| this.intersectionRight[0].distance >= 10
|| this.intersectionFront[0].distance >= 10
|| this.intersectionBack[0].distance >= 10) {
this.oktomove = true;
}
}
else {
console.log("drauflen")
this.oktomove = false;
}
this.showCasters(this.raycasterLeft, this.raycasterRight, this.raycasterFront, this.raycasterBack);
并在鼠标按下
this.oktomove = true;
this.orbitControl.enabled = false;
if (intersectRegal[intersectRegal.length - 1].object.parent.name == "regal") {
this.selected = intersectRegal[intersectRegal.length - 1].object.parent;
}
else if (intersectRegal[intersectRegal.length - 1].object.parent.parent.name == "regal") {
this.selected = intersectRegal[intersectRegal.length - 1].object.parent.parent;
}
else if (intersectRegal[intersectRegal.length - 1].object.parent.parent.parent.name == "regal") {
this.selected = intersectRegal[intersectRegal.length - 1].object.parent.parent.parent;
}
this.selectedHelper = new THREE.BoxHelper(this.selected);
this.selectedHelper.geometry.computeBoundingBox();
let bb = this.selectedHelper.geometry.boundingBox;
let originPoint = this.selected.position.clone();
originPoint.y = bb.getSize().y / 2;
originPoint.z += bb.getSize().z / 2;
this.raycasterLeft = new THREE.Raycaster(originPoint, new THREE.Vector3(-1, 0, 0));
this.raycasterRight = new THREE.Raycaster(new THREE.Vector3(originPoint.x + bb.getSize().x, originPoint.y, originPoint.z), new THREE.Vector3(1, 0, 0));
this.raycasterFront = new THREE.Raycaster(new THREE.Vector3(originPoint.x + bb.getSize().x / 2, originPoint.y, originPoint.z + bb.getSize().z / 2), new THREE.Vector3(0, 0, 1));
this.raycasterBack = new THREE.Raycaster(new THREE.Vector3(originPoint.x + bb.getSize().x / 2, originPoint.y, originPoint.z - bb.getSize().z / 2), new THREE.Vector3(0, 0, -1));
this.intersectionLeft = this.raycasterLeft.intersectObjects(this.walls, true);
this.intersectionRight = this.raycasterRight.intersectObjects(this.walls, true);
this.intersectionFront = this.raycasterFront.intersectObjects(this.walls, true);
this.intersectionBack = this.raycasterBack.intersectObjects(this.walls, true);
this.showCasters( this.raycasterLeft , this.raycasterRight , this.raycasterFront , this.raycasterBack);
这是我场景中的一些截图: 所以问题是货架停止到很晚,一旦它停止我不能再移动它。箭头是我的射线游戏者
我无法添加图片,所以我创建了一张imgur专辑 https://imgur.com/a/xOd98hc
答案 0 :(得分:2)
这是一个从头开始制作的选项。
我们的想法是使用THREE.Vector3()
的{{3}}方法。
它可能看起来很复杂,但这里的大部分内容都是为了可视化,重要的部分标有注释:
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(0, 5, 5);
camera.lookAt(scene.position);
var renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var roomGeom = new THREE.BoxGeometry(7, 2, 7);
roomGeom.translate(0, 1, 0);
var room = new THREE.Mesh(roomGeom, [
new THREE.MeshBasicMaterial({
color: "red",
side: THREE.BackSide
}),
new THREE.MeshBasicMaterial({
color: "red",
side: THREE.BackSide
}),
new THREE.MeshBasicMaterial({
color: "green",
side: THREE.BackSide
}),
new THREE.MeshBasicMaterial({
color: "green",
side: THREE.BackSide
}),
new THREE.MeshBasicMaterial({
color: "blue",
side: THREE.BackSide
}),
new THREE.MeshBasicMaterial({
color: "blue",
side: THREE.BackSide
})
]);
scene.add(room);
var objGeom = new THREE.CylinderGeometry(1, 1, 2);
objGeom.translate(0, 1, 0);
var moveObj = new THREE.Mesh(objGeom, new THREE.MeshBasicMaterial({
color: "aqua",
wireframe: true
}));
moveObj.position.set(1, 0, 0);
scene.add(moveObj);
var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
var intersects = [];
var isDragging = false;
var plane = new THREE.Plane();
var planePoint = new THREE.Vector3();
var planeNormal = new THREE.Vector3(0, 1, 0);
var movePoint = new THREE.Vector3();
var moveObjBox = new THREE.Box3();
var moveObjBoxSize = new THREE.Vector3();
moveObjBox.setFromObject(moveObj);
var boxHelper = new THREE.Box3Helper(moveObjBox, "yellow");
scene.add(boxHelper);
var moveObjShift = new THREE.Vector3();
var roomBox = new THREE.Box3().setFromObject(room);
var roomBoxMin = new THREE.Vector3();
var roomBoxMax = new THREE.Vector3();
renderer.domElement.addEventListener("mousedown", onMouseDown, false);
renderer.domElement.addEventListener("mousemove", onMouseMove, false);
renderer.domElement.addEventListener("mouseup", onMouseUp, false);
function onMouseDown(event) {
setPlane(event);
}
function onMouseMove(event) {
if (!isDragging) return;
setMouse(event);
raycaster.setFromCamera(mouse, camera);
raycaster.ray.intersectPlane(plane, movePoint);
moveObj.position.copy(movePoint).sub(moveObjShift).clamp(roomBoxMin, roomBoxMax); // clamp the position of an object
moveObjBox.setFromObject(moveObj);
}
function onMouseUp() {
isDragging = false;
}
function setPlane(event) {
setMouse(event);
raycaster.setFromCamera(mouse, camera);
moveObjBox.setFromObject(moveObj);
raycaster.ray.intersectBox(moveObjBox, planePoint)
isDragging = true;
plane.setFromNormalAndCoplanarPoint(planeNormal, planePoint);
moveObjShift.copy(planePoint).sub(moveObj.position);
roomBoxMin.copy(roomBox.min);
roomBoxMax.copy(roomBox.max);
moveObjBox.getSize(moveObjBoxSize);
// adjust clamping vectors
roomBoxMin.x += moveObjBoxSize.x * 0.5;
roomBoxMin.z += moveObjBoxSize.z * 0.5;
roomBoxMax.x -= moveObjBoxSize.x * 0.5;
roomBoxMax.z -= moveObjBoxSize.z * 0.5;
}
function setMouse(event) {
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
}
render();
function render() {
requestAnimationFrame(render);
renderer.render(scene, camera);
}

body {
overflow: hidden;
margin: 0;
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/92/three.min.js"></script>
&#13;
答案 1 :(得分:0)
他们在这里实施了展示位置限制。也许你会发现它很有用: