由于我是3D世界和3个JS世界的新手,所以我了解了大多数事情,但是在矩阵方面总是感到困惑。
我想做的是,我想在其他对象上拖动一个小对象,并且该小对象应面向主要对象的相同方向(例如,将墙上的时钟挂在墙上)。
为此,我首先尝试在旋转立方体的顶部放置一个轴辅助器,并应用简单的逻辑,即相交点将为放置小对象提供位置,而相交对象面向法线将为小对象lookAt提供方向。我做到了,但发现成功,但不合适。
然后我进行了一些计算并搜索了一些代码来计算相同的事物,现在我获得了成功。但是不明白背后的全部逻辑,为什么我们要这样做。
this.normalMatrix.getNormalMatrix(intersects[i].object.matrixWorld);
this.worldNormal.copy(intersects[i].face.normal).applyMatrix3(this.normalMatrix).normalize();
this.object.position.addVectors(intersects[i].point, this.worldNormal);
this.lookAtVec.addVectors(this.object.position,this.worldNormal.multiplyScalar(15));
this.object.lookAt(this.lookAtVec);
一个人实际上创造了一堵墙,并在上面放了一个小物体。他改变了这条线
this.object.position.addVectors(intersects[i].point, this.worldNormal);
至
this.object.position.copy(intersects[i].point);
它对他有用,但对我的轴帮手来说却不起作用。
最佳答案
只是如何选择的一种选择。查看onMouseMove()
函数的末尾:
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(-3, 5, 8);
camera.lookAt(scene.position);
var renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0x404040);
document.body.appendChild(renderer.domElement);
var controls = new THREE.OrbitControls(camera, renderer.domElement);
var light = new THREE.DirectionalLight(0xffffff, 0.5);
light.position.setScalar(10);
scene.add(light);
scene.add(new THREE.AmbientLight(0xffffff, 0.5));
var walls = [];
makeWall(Math.PI * 0.5);
makeWall(0);
makeWall(Math.PI * -0.5);
var clockGeom = new THREE.BoxBufferGeometry(1, 1, 0.1);
clockGeom.translate(0, 0, 0.05);
var clockMat = new THREE.MeshBasicMaterial({
color: "orange"
});
var clock = new THREE.Mesh(clockGeom, clockMat);
scene.add(clock);
var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
var intersects = [];
var lookAt = new THREE.Vector3();
renderer.domElement.addEventListener("mousemove", onMouseMove, false);
function onMouseMove(event) {
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
raycaster.setFromCamera(mouse, camera);
intersects = raycaster.intersectObjects(walls);
if (intersects.length === 0) return;
clock.position.copy(intersects[0].point);
clock.lookAt(lookAt.copy(intersects[0].point).add(intersects[0].face.normal));
}
render();
function render() {
requestAnimationFrame(render);
renderer.render(scene, camera);
}
function makeWall(rotY, color) {
let geom = new THREE.BoxBufferGeometry(8, 8, 0.1);
geom.translate(0, 0, -4);
geom.rotateY(rotY);
let mat = new THREE.MeshLambertMaterial({
color: Math.random() * 0x777777 + 0x777777
});
let wall = new THREE.Mesh(geom, mat);
scene.add(wall);
walls.push(wall);
}
body {
overflow: hidden;
margin: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/94/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>