我使用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;
点击鼠标时,我想&#34;拍摄&#34;来自旋转头部的射弹/子弹。但正如您可以从代码中的TODO
条评论中看到的那样,有两个函数我不知道如何实现:getMouthPosition()
和updateProjectile()
。
对于getMouthPosition()
,我想确定嘴的当前位置并在此位置产生弹丸(理想情况下,就在嘴前)。
对于updateProjectile()
,我想在弹丸首次创建时朝向头部朝向的方向移动射弹,如下所示:
如果有人能够阐明如何编写这些功能,那就太棒了。感谢。
答案 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;
}
来获取它。
结束所有这一切:你知道头部的位置,你知道它的方向,因此你可以使用这些值投射一个射弹。
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;