首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >相机沿曲线移动时不能获得一致的速度

相机沿曲线移动时不能获得一致的速度
EN

Stack Overflow用户
提问于 2017-10-30 06:49:55
回答 1查看 675关注 0票数 1

我想让相机沿着曲线移动,它可以工作,但是当经过拐角处时,相机的速度变了,看上去很慢。

代码语言:javascript
复制
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不改变,我会得到平均速度,但它不是。我不明白。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-10-30 16:12:03

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

文档说:

.getUtoTmapping ( u,距离)

在范围内给你(0 .,也在范围内返回t(0 ..1 )。然后,使用.getPoint,可以使用U和t给出与曲线末端等距的点。

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

在给定的图片中:

  • 小黄点-点,用.getPoints()法取;
  • 大红褐色点-点,沿曲线相互之间的距离为1单位;

栗色点的代码:

代码语言:javascript
复制
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);

查看代码片段的源代码,并注意getProgress()函数。

代码语言:javascript
复制
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);
}
代码语言:javascript
复制
body {
  overflow: hidden;
  margin: 0;
}
代码语言:javascript
复制
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47009475

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档