所以我有一个非常简单的情况,地平面基本上是 y=0 的位置,并且我想始终将相机保持在地面上方。我还想要感觉直观(并且与触摸兼容)的良好控件,并且我发现 OrbitControls.js 似乎最适合此目的,还因为在那里我可以通过将 maxPolarAngle 设置为小于或等于的值来轻松限制极角Math.PI/2(四分之一圈)。
不过,即使这样做,用户也可以在地面以下平移,除非完全禁用平移(我不想这样做)。手动限制以使 y 永远不会变为负数感觉很奇怪,但我认为简单地忽略 y 轴上的任何变化,例如将第 165 行(panUp 函数)更改为以下内容
panOffset.set( te[ 4 ], 0, te[ 6 ] );
panOffset.normalize();
导致了一个快速而肮脏的解决方案,满足了我的需求。
但现在用户只能通过缩放来改变相机高度。
你能想到更好的解决方案吗?也许这个帖子可以作为官方解决方案的深思熟虑,我相信我不会是唯一受益于这样的解决方案的人。
/编辑:我一开始没有标准化偏移向量,这导致了另一个问题,现在已更改。
不要进入地下:
controls.maxPolarAngle = Math.PI / 2
以防万一有人需要答案:
您可以找到相对于控制目标和相机地面位置的角度(无论高度如何)并分配 maxPolarAngle。调整你的上轴,我的是 Y。在控件更改事件内:
var centerPosition = controls.target.clone();
centerPosition.y = 0;
var groundPosition = camera.position.clone();
groundPosition.y = 0;
var d = (centerPosition.distanceTo(groundPosition));
var origin = new THREE.Vector2(controls.target.y,0);
var remote = new THREE.Vector2(0,d); // replace 0 with raycasted ground altitude
var angleRadians = Math.atan2(remote.y - origin.y, remote.x - origin.x);
controls.maxPolarAngle = angleRadians;
我在让 OrbitsControls.js 按我的意愿工作时遇到问题。最适合我的解决方案是创建我自己的 CamaraControls,它可以按照我的要求运行。我怀疑这不是您正在寻找的答案,因为它涉及一些工作。您始终可以添加自己的更新函数来限制值。
THREE.OrbitControls.clampedUpdate = function () {
THREE.OrbitControls.update.call(this);
if (this.object.position.y < 0) {
this.object.position.y = 0;
}
}
就这样,只需在 OrbitControls 中将“screenSpacePanning”设置为 false 即可!