我正在创建一个飞行动画,我有一些物体(飞机)沿曲线路径移动。我的问题是我的一些物体在沿着曲线路径行进时正在旋转。
function createPlane(image) {
return new THREE.Mesh(
new THREE.PlaneGeometry(5, 5),
new THREE.MeshPhongMaterial({ map: new THREE.TextureLoader().load('textures/planes/' + image), side: THREE.DoubleSide, transparent: true })
);
}
// this is how we get the line.vertices
// var curve = new THREE.Curve();
// line.vertices = curve.getPoints(50);
function animatePlane(plane, line, key) {
if (key > 1) {
key = 1;
} else {
key = Math.round(key * 100) / 100;
}
var curve = new THREE.CatmullRomCurve3(line.vertices), up = new THREE.Vector3(0, 1, 0), axis = new THREE.Vector3();
var angle, duration = 300, position = curve.getPointAt(key), tangent = curve.getTangentAt(key).normalize();
// rotation
axis.crossVectors(up, tangent).normalize();
angle = Math.acos(up.dot(tangent));
plane.quaternion.setFromAxisAngle(axis, angle);
// position
new TWEEN.Tween(plane.position)
.to({ x: position.x, y: position.y, z: position.z }, duration)
.onUpdate(function() {
plane.position.set(this.x, this.y, this.z);
})
.onComplete(function() {
if (key < 1) {
key += 0.02;
} else {
key = 0;
}
animatePlane(plane, line, key);
})
.start();
}
// lines
var point = latLongToVector3(14.512274, 121.016508, radius, 0), // Philippines
line1 = createCurveLine(createSphereArc(point, latLongToVector3(2.745364, 101.707079, radius, 0), 0.3), green, 'MALAYSIA');
animatePlane(createPlane('airplane.png'), line1, 0);
以上代码是我创建的方式以及沿曲线路径移动对象的方式。
请注意,曲线路径是动态创建的,从上面的屏幕截图是从菲律宾到其他国家,但它可能来自其他国家/地区。 曲线路径可能位于地球的不同部分,例如,来自澳大利亚(位于地球的底部)前往其他国家。
当我的飞机沿曲线路径移动时,我能做些什么来保持我的飞机直立吗?
答案 0 :(得分:0)
我现在通过使用Frenet-Serret公式(TNB Frame)来实现它。 我使用Tangent,Normal和Binormal来创建矩阵(Matrix4),然后使用该矩阵通过使用.setRotationFromMatrix()来设置平面的旋转。
现在这是为飞机设置动画的代码:
function animatePlane(plane, line, key) {
if (key > 1) {
key = 1;
} else {
key = Math.round(key * 100) / 100;
}
var curve = new THREE.CatmullRomCurve3(line.vertices), matrix = new THREE.Matrix4();
var duration = 300, position = curve.getPointAt(key);
if ((key > 0) && (key < 1)) {
var D = curve.getPointAt(1).normalize(), X = plane.position.clone().normalize();
var T = position.clone().normalize(), B = curve.getTangentAt(key), N = new THREE.Vector3();
N.crossVectors(D, T).normalize();
matrix.set(
N.x, B.x, T.x, X.x,
N.y, B.y, T.y, X.y,
N.z, B.z, T.z, X.z,
0, 0, 0, 1
);
plane.setRotationFromMatrix(matrix);
}
new TWEEN.Tween(plane.position)
.to({ x: position.x, y: position.y, z: position.z }, duration)
.onUpdate(function() {
plane.position.set(this.x, this.y, this.z);
})
.onComplete(function() {
if (key < 1) {
key += 0.02;
} else {
key = 0;
}
animatePlane(plane, line, key);
})
.start();
}
并添加此项以使平面位于曲线路径上方:
var plane1 = createPlane('airplane.png');
plane1.renderOrder = 1;
plane1.onBeforeRender = function(renderer) {
renderer.clearDepth();
}
animatePlane(plane1, line1, 0);