相机意外转动(three.js + tween + lookat)
unexpected turn of the camera (three.js + tween + lookat)
我有一个关于 three.js + tween + lookat 的问题
这是一个例子:https://intera3d.ru/tween_test/tokyo.html
我希望当按下“TWEEN”按钮时,相机从上方查看 3D 模型。
事情就这样发生了,但最后镜头/3D模型出现了意想不到的转向。
如何避免这种情况?
这里是“tween”函数代码:
function TWEEN_begin_CAMERA_1() {
const tweenCamera1 = new TWEEN.Tween(
{x: camera.position.x, y: camera.position.y, z: camera.position.z,
lookAtX: 0, lookAtY: 0, lookAtZ: 0}
)
.to( {x: 0, y: 20, z: 0, lookAtX: 0, lookAtY: 0, lookAtZ: 0}, 1000 )
const updateCamera = function (object, elapsed) {
camera.position.set(object.x, object.y, object.z);
camera.lookAt(new THREE.Vector3(object.lookAtX, object.lookAtY, object.lookAtZ))
}
tweenCamera1.onUpdate(updateCamera)
tweenCamera1.start()
}
非常感谢您的帮助!
这是一个 THREE.Spherical
的示例,它不允许将相机设置为 x
=0 和 z
=0(在任何 y
) ,在文档中查看方法 .makeSafe()
的作用:
body{
overflow: hidden;
margin: 0;
}
<button id="btn_Tween" style="position:absolute; margin: 10px;">TWEENME</button>
<script type="module">
import * as THREE from "https://cdn.skypack.dev/three@0.134.0";
import {OrbitControls} from "https://cdn.skypack.dev/three@0.134.0/examples/jsm/controls/OrbitControls.js";
import {TWEEN} from "https://cdn.skypack.dev/three@0.134.0/examples/jsm/libs/tween.module.min.js"
let scene = new THREE.Scene();
let camera = new THREE.PerspectiveCamera(60, innerWidth / innerHeight, 1, 1000);
camera.position.set(0, 5, 10);
let renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);
window.addEventListener("resize", () => {
camera.aspect = innerWidth / innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(innerWidth, innerHeight);
});
let controls = new OrbitControls(camera, renderer.domElement);
let light = new THREE.DirectionalLight(0xffffff, 1);
light.position.setScalar(1);
scene.add(light, new THREE.AmbientLight(0xffffff, 0.5));
scene.add(new THREE.GridHelper());
scene.add(new THREE.Mesh(
new THREE.BoxGeometry(5, 5, 5),
new THREE.MeshLambertMaterial(
{
map: new THREE.TextureLoader().load("https://threejs.org/examples/textures/uv_grid_opengl.jpg")
}
)
));
btn_Tween.addEventListener("click", ()=> {
let spherical = new THREE.Spherical();
spherical.setFromVector3(camera.position);
spherical.radius = 20;
spherical.phi = 0;
spherical.makeSafe();
let v = new THREE.Vector3().setFromSpherical(spherical);
let t = new TWEEN.Tween(camera.position).to(v, 2000).onUpdate(() => {
camera.lookAt(scene.position);
controls.update();
});
t.start();
});
renderer.setAnimationLoop(() => {
TWEEN.update();
renderer.render(scene, camera);
});
</script>
我有一个关于 three.js + tween + lookat 的问题 这是一个例子:https://intera3d.ru/tween_test/tokyo.html 我希望当按下“TWEEN”按钮时,相机从上方查看 3D 模型。
事情就这样发生了,但最后镜头/3D模型出现了意想不到的转向。
如何避免这种情况?
这里是“tween”函数代码:
function TWEEN_begin_CAMERA_1() {
const tweenCamera1 = new TWEEN.Tween(
{x: camera.position.x, y: camera.position.y, z: camera.position.z,
lookAtX: 0, lookAtY: 0, lookAtZ: 0}
)
.to( {x: 0, y: 20, z: 0, lookAtX: 0, lookAtY: 0, lookAtZ: 0}, 1000 )
const updateCamera = function (object, elapsed) {
camera.position.set(object.x, object.y, object.z);
camera.lookAt(new THREE.Vector3(object.lookAtX, object.lookAtY, object.lookAtZ))
}
tweenCamera1.onUpdate(updateCamera)
tweenCamera1.start()
}
非常感谢您的帮助!
这是一个 THREE.Spherical
的示例,它不允许将相机设置为 x
=0 和 z
=0(在任何 y
) ,在文档中查看方法 .makeSafe()
的作用:
body{
overflow: hidden;
margin: 0;
}
<button id="btn_Tween" style="position:absolute; margin: 10px;">TWEENME</button>
<script type="module">
import * as THREE from "https://cdn.skypack.dev/three@0.134.0";
import {OrbitControls} from "https://cdn.skypack.dev/three@0.134.0/examples/jsm/controls/OrbitControls.js";
import {TWEEN} from "https://cdn.skypack.dev/three@0.134.0/examples/jsm/libs/tween.module.min.js"
let scene = new THREE.Scene();
let camera = new THREE.PerspectiveCamera(60, innerWidth / innerHeight, 1, 1000);
camera.position.set(0, 5, 10);
let renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);
window.addEventListener("resize", () => {
camera.aspect = innerWidth / innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(innerWidth, innerHeight);
});
let controls = new OrbitControls(camera, renderer.domElement);
let light = new THREE.DirectionalLight(0xffffff, 1);
light.position.setScalar(1);
scene.add(light, new THREE.AmbientLight(0xffffff, 0.5));
scene.add(new THREE.GridHelper());
scene.add(new THREE.Mesh(
new THREE.BoxGeometry(5, 5, 5),
new THREE.MeshLambertMaterial(
{
map: new THREE.TextureLoader().load("https://threejs.org/examples/textures/uv_grid_opengl.jpg")
}
)
));
btn_Tween.addEventListener("click", ()=> {
let spherical = new THREE.Spherical();
spherical.setFromVector3(camera.position);
spherical.radius = 20;
spherical.phi = 0;
spherical.makeSafe();
let v = new THREE.Vector3().setFromSpherical(spherical);
let t = new TWEEN.Tween(camera.position).to(v, 2000).onUpdate(() => {
camera.lookAt(scene.position);
controls.update();
});
t.start();
});
renderer.setAnimationLoop(() => {
TWEEN.update();
renderer.render(scene, camera);
});
</script>