【发布时间】:2015-06-17 17:10:10
【问题描述】:
在我的示例中,我正在将一辆坦克移动到一座桥上。我可以看到这个问题有两种方法,一种是让物理处理数学,另一种是手动计算车辆的高度和旋转值(这是我想采用的方法)。
到目前为止,我已经通过各种不同的方法取得了一些成功,我将在下面描述它们:
首先我使用的是轴对齐边界框 (AABB)。从这里我设置一个任意高度并从 4 个角向下投影以找到与地面地形相交的 4 个点。在这 4 个点上,使用 x 和 z 轴的叉积计算一个向上的向量:
// slopePoints[4] are the 4 points that interset the ground from the downward raycast
// vec2, vec6, vec7 make up the x and z axis for the base of the tank
var xDirSlope = slopePoints[3].clone().sub( slopePoints[0] ).normalize();
var zDirSlope = slopePoints[2].clone().sub( slopePoints[3] ).normalize();
var slopeNormalVector = new THREE.Vector3().crossVectors( xDirSlope, zDirSlope );
var xDirObjectBase = vec6.clone().sub( vec7 ).normalize();
var zDirObjectBase = vec2.clone().sub( vec6 ).normalize();
var baseNormalVector = new THREE.Vector3().crossVectors( xDirObjectBase, zDirObjectBase );
所以现在我有两个归一化向量(1)代表坦克“应该”所在位置的向上向量,(2)代表坦克“现在”所在位置的向上向量。
(1) 源自投射在地形上的光线 (2) 是坦克的AABB包围盒的底部
我的下一步是计算两个向量与变换所需的轴之间的角度如下:
var radians = Math.acos( baseNormalVector.dot( slopeNormalVector ) );
var axis = new THREE.Vector3().crossVectors( baseNormalVector, slopeNormalVector );
所以现在已经计算了以弧度为单位的角度和转换轴我应该能够使用以下方法在所需的轴上旋转我的坦克:
var matrix = new THREE.Matrix4().makeRotationAxis( axis, radians );
object.applyMatrix( matrix );
当我应用这个逻辑时,我可以看到坦克旋转以匹配桥梁的轮廓,但随后它会拉动一个轮子并最终正确地停在桥梁的另一侧。
我的观察是,当坦克进入桥梁的起点时,它应该在它的 x 轴上旋转,但是当它接近中间标记时,旋转应该从正三角洲变为负三角洲,但事实并非如此只是继续上升。
其他方法有:
// 使用四元数坦克的行为很奇怪,甚至在垂直之前都没有移动到桥上
quaternion = new THREE.Quaternion().setFromUnitVectors( baseNormalVector, slopeNormalVector );
matrix = new THREE.Matrix4().makeRotationFromQuaternion( quaternion );
// By calculating the rotational delta as I move over the bridge
radians = baseNormalVector.angleTo( slopeNormalVector );
object.rotateX( radians )
我尝试计算在桥上移动时的旋转增量,因此当我开始时,我有一个 + 角,当我超过 45 度标记时,我更改为 - 角,以使坦克在移动到中心点时恢复平坦桥,然后反向使坦克下来。虽然我对这种方法不满意,但效果还不错,而且当你改变坦克和桥梁的方向时也会导致问题。
任何帮助指导将不胜感激。
【问题讨论】:
标签: three.js