相机沿曲线移动时无法获得均匀的速度

时间:2017-10-30 06:49:56

标签: three.js

我想让相机沿着曲线移动,它可以工作,但是当通过转弯时,相机速度发生了变化,看起来很慢。

curve = new THREE.CatmullRomCurve3(vectors);
curve.type = 'catmullrom';
curve.tension = 0.2;
this.MKY.Camera.current = this.roamCamera;
cameraWrap.add(this.roamCamera);
this.MKY.scene.add(cameraWrap);
this.MKY.update.push(roam);

function roam() {
    if(!isAutoRoam){return}
    if(progress>1 || progress==1){
        progress = 0;
        return
    }
    progress += 0.0005;
    var position = curve.getPointAt(progress);
    position.y += 1.5;
    var tangent = curve.getTangentAt(progress);
    cameraWrap.position.copy(position);
    cameraWrap.lookAt(position.sub(tangent));
};

getPointAt根据弧长返回曲线中相对位置处的点矢量。我想如果progress没有改变,我会得到平均速度,但事实并非如此。我没有参加。

1 个答案:

答案 0 :(得分:0)

enter image description here

有一种方法,使用.getUtoTmapping()的{​​{1}}方法(在示例中,它是THREE.Curve())。

documentation说:

.getUtoTmapping(u,distance)

在范围(0 ... 1)中给定u,也返回范围(0 ... 1)中的t。然后,使用.getPoint,可以使用u和t为您提供与曲线末端等距的点。

所以,当你在这个方法中提供第二个参数时,如果我从源代码中正确地得到它,它会忽略第一个参数,因此你可以通过它上的距离找到曲线上的点。

在给定的图片中:

  • 小黄点 - 用THREE.CatmullRomCurve3方法拍摄的点数;
  • 大栗色点 - 点,沿曲线彼此之间的距离是1个单位;

栗色点的代码:

.getPoints()

查看代码段的源代码,并注意var unitPoints = []; for (let i = 0; i < spline.getLength(); i++){ let p = spline.getUtoTmapping(0, i); let p1 = spline.getPoint(p); unitPoints.push(p1); } var unitPointsGeometry = new THREE.Geometry(); unitPointsGeometry.vertices = unitPoints; var units = new THREE.Points(unitPointsGeometry, new THREE.PointsMaterial({size: .125, color: "maroon"})); scene.add(units); 函数。

&#13;
&#13;
getProgress()
&#13;
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, .1, 1000);
camera.position.set(0, 1.5, 3);
var renderer = new THREE.WebGLRenderer({
  antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0x181818);
document.body.appendChild(renderer.domElement);

var controls = new THREE.OrbitControls(camera, renderer.domElement);

scene.add(new THREE.GridHelper(4, 8));

var spline = new THREE.CatmullRomCurve3(
  [
    new THREE.Vector3(-2, 0, 0),
    new THREE.Vector3(-1.9, .1, .1),
    new THREE.Vector3(1, 1, 1),
    new THREE.Vector3(0, -1, -2),
    new THREE.Vector3(2, 0, 1)
  ]
);
spline.closed = true;
var splinePoints = spline.getPoints(200);
var lineGeom = new THREE.Geometry();
lineGeom.vertices = splinePoints;
var line = new THREE.Line(lineGeom, new THREE.LineBasicMaterial({
  color: "orange"
}));
scene.add(line);

var sPoints = new THREE.Points(lineGeom, new THREE.PointsMaterial({
  size: .0312,
  color: "yellow"
}));
scene.add(sPoints);

var unitPoints = [];
for (let i = 0; i < spline.getLength(); i++) {
  let p = spline.getUtoTmapping(0, i);
  let p1 = spline.getPoint(p);
  unitPoints.push(p1);
}
var unitPointsGeometry = new THREE.Geometry();
unitPointsGeometry.vertices = unitPoints;
var units = new THREE.Points(unitPointsGeometry, new THREE.PointsMaterial({
  size: .125,
  color: "maroon"
}));
scene.add(units);

var marker = new THREE.Mesh(new THREE.SphereGeometry(0.125, 4, 2), new THREE.MeshBasicMaterial({
  color: "red",
  wireframe: true
}));
marker.geometry.translate(0, 0, 0.0625);
marker.geometry.vertices[2].z = 0.25;
marker.geometry.vertices[4].z = 0;
scene.add(marker);

var markerLineGeometry = new THREE.Geometry();
markerLineGeometry.vertices.push(new THREE.Vector3(), new THREE.Vector3());
var line = new THREE.Line(markerLineGeometry, new THREE.LineBasicMaterial({
  color: "white"
}));
scene.add(line);

var clock = new THREE.Clock();
var progress = 0;

var totalLength = spline.getLength();
var speed = .66; // unit a second
var ratio = speed / totalLength;
var shift = 0;
var basePoint = 0;
var lookAtPoint = 0;

var oldPosition = spline.getPoint(0);
var speedVector = new THREE.Vector3();

function setProgress(delta) {
  if (progress > totalLength) progress = 0;
  shift = progress + speed * 2;
  shift = shift > totalLength ? shift - totalLength : shift;

  basePoint = spline.getUtoTmapping(0, progress);

  lookAtPoint = spline.getUtoTmapping(0, shift);

  line.geometry.vertices[0].copy(spline.getPoint(basePoint));
  line.geometry.vertices[1].copy(spline.getPoint(lookAtPoint));
  line.geometry.verticesNeedUpdate = true;

  marker.position.copy(line.geometry.vertices[0]);
  marker.lookAt(line.geometry.vertices[1]);

  progress += speed * delta;
}

render();

function render() {
  requestAnimationFrame(render);
  setProgress(clock.getDelta());
  renderer.render(scene, camera);
}
&#13;
body {
  overflow: hidden;
  margin: 0;
}
&#13;
&#13;
&#13;