我想让相机沿着曲线移动,它可以工作,但是当通过转弯时,相机速度发生了变化,看起来很慢。
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
没有改变,我会得到平均速度,但事实并非如此。我没有参加。
答案 0 :(得分:0)
有一种方法,使用.getUtoTmapping()
的{{1}}方法(在示例中,它是THREE.Curve()
)。
.getUtoTmapping(u,distance)
在范围(0 ... 1)中给定u,也返回范围(0 ... 1)中的t。然后,使用.getPoint,可以使用u和t为您提供与曲线末端等距的点。
所以,当你在这个方法中提供第二个参数时,如果我从源代码中正确地得到它,它会忽略第一个参数,因此你可以通过它上的距离找到曲线上的点。
在给定的图片中:
THREE.CatmullRomCurve3
方法拍摄的点数; 栗色点的代码:
.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);
函数。
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;