我不想使用 camera.rotation 或使用 lookAt() 函数旋转相机,而是将外观矢量直接传递给相机...是否可以直接设置相机外观矢量,是否可以读取外观来自相机的矢量?
4 回答
相机没有“look vector”,因此您无法设置它。
但是,您可以point
通过将您的外观矢量添加到相机的位置,然后调用
camera.lookAt( point );
以下是如何确定相机正在看的方向,假设相机没有父级(场景除外)。
相机向下看它的内部负 z 轴,因此创建一个指向负 z 轴的向量:
var vector = new THREE.Vector3( 0, 0, - 1 );
现在,对应用于相机的向量应用相同的旋转:
vector.applyQuaternion( camera.quaternion );
生成的矢量将指向相机正在寻找的方向。
或者,您可以使用以下方法,即使相机是另一个对象的子对象,该方法也有效:
camera.getWorldDirection( dirVector );
三.js r.73
上面的答案包装为一个实用程序,这就是我对我的三个实用程序所做的事情:
THREE.Utils = {
cameraLookDir: function(camera) {
var vector = new THREE.Vector3(0, 0, -1);
vector.applyEuler(camera.rotation, camera.eulerOrder);
return vector;
}
};
调用它THREE.Utils.cameraLookDir(camera);
这些其他答案非常有见地,但并不完全正确。该代码返回一个向量,该向量指向与相机指向的方向相同的方向。这是一个很好的开始!
但除非相机位于原点 (0, 0, 0)(或恰好位于将原点连接到旋转矢量点的线段上,但不超过该点,因此该点位于相机后面),否则相机将不会不要看那个点。显然——只是常识——相机的位置也会影响正在观察的点。考虑一下!!
无论相机在哪里,相机方法lookAt()
都会查看 3D 空间中的一个点。因此,要获得相机正在查看的点,您需要通过调用来调整相机位置:
vec.add( camera.position );
还值得一提的是,相机不是在看一个点,而是在向下看无限数量的点,每个点与相机的距离不同。其他答案中的代码返回一个长度正好为一个单位的向量,因为将四元数应用于归一化 z 轴向量 (0, 0, -1) 会返回另一个归一化向量(在不同方向上)。x
要计算距相机任意距离的观察点,请使用:
THREE.Vector3( 0, 0, -x ).applyQuaternion( camera.quaternion ).add( camera.position );
这会在距原点一定距离的 z 轴上取一个点,将其x
旋转到相机的方向,然后通过添加相机的位置来创建一个“世界点”。我们想要一个“世界点”(而不仅仅是一个“相对于相机点”),因为camera.lookAt()
也需要一个“世界点”作为参数。
我所做的是在渲染场景之前使用方法lookAt(Vector),如下面的代码,只需在新的html文件上尝试使用它:)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style >
*{
margin: 0 ;
}
#WebGlElement {
height: 500px;
width: 500px;
background-color: red
}
</style>
</head>
<body>
<script src="js/three.min.js"></script>
<div id="WebGlElement"></div>
<script>
var contianer = document.getElementById("WebGlElement");
var origin = new THREE.Vector3(0,0,0);
// CREATE THREE BASIC ELEMENTS
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 40, 300/300, 1, 1000 );
var renderer = new THREE.WebGLRenderer();
// SET RENDERER AND ATTACH IT TO BODY
renderer.setSize( 500, 500 );
//document.body.appendChild( renderer.domElement );
contianer.appendChild( renderer.domElement);
// CREATE A GEOMETRY AND ADD IT TO SCENE
/*var geometry = new THREE.BoxGeometry( 1, 1, 5 );
var material = new THREE.MeshBasicMaterial( { color: 0x1abc9c } );
material.wireframe = true ;
material.wireframeLinewidth = 0.1 ;
var cube = new THREE.Mesh( geometry, material );
scene.add( cube );*/
var geometry = new THREE.Geometry();
geometry.elementsNeedUpdate=true;
geometry.vertices.push(
new THREE.Vector3( -0, 1, 0 ),
new THREE.Vector3( -1, -1, 0 ),
new THREE.Vector3( 1, -1, 0 )
);
geometry.faces.push(
new THREE.Face3( 0, 1, 2 ),
new THREE.Face3( 2, 1, 0 )
);
var material = new THREE.MeshBasicMaterial( { color: 0x1abc9c } );
//material.wireframe = true ;
//material.wireframeLinewidth = 0.1 ;
var cube = new THREE.Mesh( geometry, material );
scene.add( cube );
var axisHelper = new THREE.AxisHelper( 1 );
scene.add( axisHelper );
// POSITION OF CAMER ON Z
camera.position.z = 5;
camera.position.y = 5;
camera.up = new THREE.Vector3(0,0,1);
var dir = 1;
var number = 0.115
// CREATE FUNCTION FOR RENDER
var render = function () {
requestAnimationFrame( render );
//circle.rotation.x += 0.01;
if ( camera.position.x> 5) {
dir = -1;
}
if ( camera.position.x< -5) {
dir = 1;
}
camera.lookAt(cube.position);
//camera.rotation.y += 0.015 * dir;
camera.position.x += number * dir;
renderer.render(scene, camera);
};
// EXECUTE FIRST RENDER
render();
</script>
</body>
</html>