将对象保留在房间

时间:2018-05-28 07:16:45

标签: javascript three.js

我有一个我创建的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

2 个答案:

答案 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;
&#13;
&#13;

答案 1 :(得分:0)

他们在这里实施了展示位置限制。也许你会发现它很有用:

http://furnishup.github.io/blueprint3d/example/