使用OBJLoader加载对象;如何计算其中某些东西的位置? (three.js所)

时间:2017-10-10 08:13:09

标签: javascript three.js

我使用three.js和OBJLoader渲染3D人体头部:



let renderer, camera, scene, head, light, projectiles;

new THREE.OBJLoader().load(objUrl, initialize);

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

  camera = new THREE.PerspectiveCamera(55, window.innerWidth / window.innerHeight);

  scene = new THREE.Scene();

  head = obj.clone();
  head.children.forEach(child => child.material = new THREE.MeshPhongMaterial({ color: "#ffc700" }));
  head.position.y = -34;
  head.position.z = -110;
  scene.add(head);
  
  light = new THREE.SpotLight();
  light.target = head;
  scene.add(light);
  
  projectiles = [];

  window.addEventListener("mousedown", createProjectile, false);

  animate();
}

function animate() {
  head.rotation.y += THREE.Math.degToRad(1);

  projectiles.forEach(updateProjectile);

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

function createProjectile() {
  let projectile = new THREE.Mesh();
  projectile.material = new THREE.MeshToonMaterial({ color: "#ff0000" });
  projectile.geometry = new THREE.SphereGeometry(3, 20, 20);
  projectile.position.copy(getMouthPosition());
  scene.add(projectile);
  projectiles.push(projectile);
}

function updateProjectile(projectile) {
  // TODO: Move projectile in the direction the mouth was facing when projectile was first created.
  projectile.position.x += 2;
}

function getMouthPosition() {
  // TODO: Determine the world position of the mouth.
  let box = new THREE.Box3().setFromObject(head);
  return box.getCenter();
}

body {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  border: 0;
}

canvas {
  display: block;
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/86/three.js">
</script>

<script src="https://wzrd.in/standalone/three-obj-loader@1.1.3">
</script>

<script>
  threeObjLoader(THREE);
  objUrl = "https://cdn.rawgit.com/mrdoob/three.js/f32fc45/examples/obj/walt/WaltHead.obj";
</script>
&#13;
&#13;
&#13;

点击鼠标时,我想&#34;拍摄&#34;来自旋转头部的射弹/子弹。但正如您可以从代码中的TODO条评论中看到的那样,有两个函数我不知道如何实现:getMouthPosition()updateProjectile()

对于getMouthPosition(),我想确定嘴的当前位置并在此位置产生弹丸(理想情况下,就在嘴前)。

对于updateProjectile(),我想在弹丸首次创建时朝向头部朝向的方向移动射弹,如下所示:

example

如果有人能够阐明如何编写这些功能,那就太棒了。感谢。

1 个答案:

答案 0 :(得分:1)

看。不知怎的,你会得到嘴巴所在的位置(在head所在的[0, 25, 20]群的坐标中).localToWorld(v)。然后,为了获得旋转头的嘴部位置,您可以使用head.localToWorld(mouthPosition.copy(spawnPoint.position)); 方法,如下所示:

spawnPoint

.getWorldDirection()是&#34;帮助&#34;对象以指示我们的生成点的位置。

此外,您必须知道您的头部指向的位置。您可以使用head对象的另一种方法let renderer, camera, scene, head, light, projectiles, spawnPoint, clock = new THREE.Clock(), delta = 0; new THREE.OBJLoader().load(objUrl, initialize); function initialize(obj) { renderer = new THREE.WebGLRenderer({ alpha: true, antialias: true }); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); camera = new THREE.PerspectiveCamera(55, window.innerWidth / window.innerHeight); scene = new THREE.Scene(); head = obj.clone(); head.children.forEach(child => child.material = new THREE.MeshPhongMaterial({ color: Math.random() * 0xffffff })); head.position.y = -34; head.position.z = -110; scene.add(head); light = new THREE.SpotLight(); light.target = head; scene.add(light); spawnPoint = new THREE.Mesh(new THREE.SphereGeometry(1, 4, 2), new THREE.MeshBasicMaterial({color: "red", wireframe: true})); spawnPoint.position.set(0, 25, 20); head.add(spawnPoint); projectiles = []; window.addEventListener("mousedown", event => { createProjectile(); }, false); animate(); } function animate() { delta = clock.getDelta(); requestAnimationFrame(animate); head.rotation.y += THREE.Math.degToRad(20) * delta; projectiles.forEach(p => { p.position.addScaledVector(p.userData.direction, p.userData.speed * delta); }); renderer.render(scene, camera); } function createProjectile() { let projectile = new THREE.Mesh(); projectile.material = new THREE.MeshToonMaterial({ color: 0xff0000 }); projectile.geometry = new THREE.SphereGeometry(3, 16, 12); let pos = getMouthPosition(); console.log("pos", pos); projectile.position.copy(pos); projectile.userData.direction = new THREE.Vector3().copy(head.getWorldDirection().normalize()); console.log(projectile.userData.direction); projectile.userData.speed = 50; scene.add(projectile); projectiles.push(projectile); console.log(projectiles); } function getMouthPosition() { let mouthPosition = new THREE.Vector3(); console.log("spawnPoint", spawnPoint); head.localToWorld(mouthPosition.copy(spawnPoint.position)); console.log("mouthPosition", mouthPosition); return mouthPosition; }来获取它。

结束所有这一切:你知道头部的位置,你知道它的方向,因此你可以使用这些值投射一个射弹。

&#13;
&#13;
body {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  border: 0;
}

canvas {
  display: block;
}
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/86/three.js">
</script>

<script src="https://wzrd.in/standalone/three-obj-loader@1.1.3">
</script>

<script>
  threeObjLoader(THREE);
  objUrl = "https://cdn.rawgit.com/mrdoob/three.js/f32fc45/examples/obj/walt/WaltHead.obj";
</script>
&#13;
var responseObject = json.parse(response)
&#13;
&#13;
&#13;