Three.js - 如何相对于物体的位置和方向设置位置?

6

我试图让我的第二个对象位于已旋转的第一个对象(-distance)正后方。

假设我有两个对象:

var object1 = new THREE.Object3D();
object1.position.set(5, 10, 53);
object1.rotateX(1);
object1.rotateY(1.5);


var distance = 20; //place object2 20 units behind object1
var object2 = new THREE.Object3D();
object2.position.set( /*position object2 right behind object1 -distance */);
object2.lookAt(object1);

在这种情况下,我该如何将已旋转的object1后面放置object2
二维可视示例。不按比例。 enter image description here
2个回答

4

这样做:

let camera, scene, renderer;

init();
animate();

function init() {

  camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.1, 100);
  camera.position.set(5, 10, 55);

  scene = new THREE.Scene();

  const geometry = new THREE.PlaneGeometry();
  const material = new THREE.MeshNormalMaterial();

  const mesh1 = new THREE.Mesh(geometry, material);
  mesh1.position.set(5, 10, 53);
  mesh1.rotateX(1);
  mesh1.rotateY(1.5);
  scene.add(mesh1);

  const mesh2 = new THREE.Mesh(geometry, material);
  scene.add(mesh2);

  const v1 = new THREE.Vector3(0, 0, 1).applyQuaternion(mesh1.quaternion);
  mesh2.quaternion.copy(mesh1.quaternion);
  mesh2.position.copy(mesh1.position).add(v1.multiplyScalar(-2));

  renderer = new THREE.WebGLRenderer({
    antialias: true
  });
  renderer.setSize(window.innerWidth, window.innerHeight);
  document.body.appendChild(renderer.domElement);

  const controls = new THREE.OrbitControls(camera, renderer.domElement);
  controls.target.copy(mesh1.position);
  controls.update();

}

function animate() {

  requestAnimationFrame(animate);
  renderer.render(scene, camera);

}
body {
      margin: 0;
}
<script src="https://cdn.jsdelivr.net/npm/three@0.128/build/three.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three@0.128/examples/js/controls/OrbitControls.js"></script>

这个想法是将object1的旋转应用到object2上,并且用它来计算位于object1后面的位置。这是通过将旋转应用于矢量,然后通过距离值(在上述情况下为-2)对其进行缩放,最后加上object1的位置值来实现的。


2
在这个特定的用例中,您可以将object2添加到object1中,并将object2的位置简单设置为您想要的距离的单轴值,在任何作为object1“后面”的轴上。
// given: object1, object2
// assuming: the meshes' "forward" direction is locally +Z, both "up" are +Y

scene.add( object1 )

object1.add( object2 )

object2.position.z = -distance

一些澄清:

网格的“前进”方向在本地是+Z

这对于确定“后面”意味着什么非常重要。例如,汽车的前灯会指向+Z方向。

两个“上”都是+Y

这是模型定向的另一个方面。如果两个模型的“上”方向都是+Y,则它们相对彼此“竖直”。这就像说对于两辆汽车,它们的车顶都朝向+Y方向。

工作原理:

假设两个网格-在其基本定向中-定向相同,则您可以通过相对于object1操纵object2来操作它。您可以通过使object2成为object1的子级来实现这一点,这意味着object2将在object1的局部空间而不是世界空间中执行其变换。这是可能的,因为MeshObject3D的派生类,后者是three.js中的通用3D容器。作为子代,object2自动继承object1的变换,因此当您移动/旋转object1时,object2将跟随。

这种方法不起作用的情况:

您可以继续将子级链接在一起,但是在某些情况下,您可能希望使链中的一个对象相对于外部或全局对象执行某些操作。在执行所需操作之前,需要进行一些额外的步骤来解开变换。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接