gpt4 book ai didi

Three.js 将对象移动到相机前面

转载 作者:行者123 更新时间:2023-12-05 09:11:51 27 4
gpt4 key购买 nike

你好,我正在尝试将一个物体移动到相机前面,当它到达目标位置时,我想让它停下来。但它不起作用。

function objectToCamera(mX, mY, object)
{
var vector = new THREE.Vector3(mX, mY, 1);
vector.unproject(camera);
vector.sub(object.position);

var dx = object.position.x - camera.position.x;
var dy = object.position.y - camera.position.y;
var dz = object.position.z - camera.position.z;

var distance = Math.sqrt(dx*dx + dy*dy + dz*dz);

if(lastDistance < distance && lastDistance != -1)
keepOut = -1;

lastDistance = distance;

setTimeout(function(){
if( distance > 200 && keepOut == 1)
{
var amount = (1)*(indexForZoom/3);

amount = (amount>15) ? 15 : (1)*(indexForZoom/3);

if(distance - amount < 200)
amount = (distance-200)+1;

indexForZoom++;
object.translateZ(amount);
controls.target.addVectors(controls.target,vector.setLength(amount));
objectToCamera(mX, mY, object)
}
else
{
// stopForZoom = 1;
keepOut = -1;
objectClickHandler(object.name, object);
}
}, 10);
}

我正在检查相机和物体之间的距离,如果达到目标距离,我会让它停止,但它不起作用。在坐标中,如果 i 在正 X 坐标中,则距离减小,否则,距离增加。

我认为,在我的代码中,距离应该一直在减小,但事实并非如此。

请帮忙。谢谢。

Image to explain my case

最佳答案

您可以使用 object.position.lerp(target, amount) 将对象移向目标。数量是一个从 0 到 1 的值,1 = 100% 一直到目标,0.5 = 50% 到目标。

如果你想以固定的速度移动,那么你可以得到到目标的距离

distance = object.position.distanceTo(target);

假设您希望每次交互最多 0.1 个单位。然后

moveSpeed = 0.1;
distance = object.position.distanceTo(target);
amount = Math.min(moveSpeed, distance) / distance;
object.position.lerp(target, amount)

剩下的就是选择目标了。

摄像头前的位置是

const distanceFromCamera = 3;  // 3 units
const target = new THREE.Vector3(0, 0, -distanceToCamera);
target.applyMatrix4(camera.matrixWorld);

例如,如果您移动相机(用鼠标拖动,使用滚轮)。注意:在代码中,速度被调整为与帧速率无关。

function main() {
const canvas = document.querySelector('#c');
const renderer = new THREE.WebGLRenderer({canvas});

const fov = 45;
const aspect = 2; // the canvas default
const near = 0.1;
const far = 1000;
const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
camera.position.set(0, 10, 20);

const controls = new THREE.OrbitControls(camera, canvas);
controls.target.set(0, 0, 0);
controls.update();

const scene = new THREE.Scene();
scene.background = new THREE.Color('lightblue');

{
const color = 0xFFFFFF;
const intensity = 1;
const light = new THREE.DirectionalLight(color, intensity);
light.position.set(0, 10, 0);
light.target.position.set(-5, 0, 0);
scene.add(light);
scene.add(light.target);
}

const gridHelper = new THREE.GridHelper(100, 10);
scene.add(gridHelper);
gridHelper.position.set(0, -5, 0);

const cube = new THREE.Mesh(
new THREE.BoxBufferGeometry(1, 1, 1),
new THREE.MeshPhongMaterial({color: 'red'}),
);
scene.add(cube);

function resizeRendererToDisplaySize(renderer) {
const canvas = renderer.domElement;
const width = canvas.clientWidth;
const height = canvas.clientHeight;
const needResize = canvas.width !== width || canvas.height !== height;
if (needResize) {
renderer.setSize(width, height, false);
}
return needResize;
}

let then = 0;
function render(now) {
now *= 0.001; // convert to seconds
const deltaTime = now - then;
then = now;

if (resizeRendererToDisplaySize(renderer)) {
const canvas = renderer.domElement;
camera.aspect = canvas.clientWidth / canvas.clientHeight;
camera.updateProjectionMatrix();
}

cube.rotation.x = now;
cube.rotation.y = now * 1.1;

// move cube in front of camera
{
const distanceFromCamera = 3; // 3 units
const target = new THREE.Vector3(0, 0, -distanceFromCamera);
target.applyMatrix4(camera.matrixWorld);

const moveSpeed = 15; // units per second
const distance = cube.position.distanceTo(target);
if (distance > 0) {
const amount = Math.min(moveSpeed * deltaTime, distance) / distance;
cube.position.lerp(target, amount);
cube.material.color.set('green');
} else {
cube.material.color.set('red');
}
}

renderer.render(scene, camera);

requestAnimationFrame(render);
}

requestAnimationFrame(render);
}

main();
body { margin: 0; }
#c { width: 100vw; height: 100vh; display: block; }
<script src="https://threejsfundamentals.org/threejs/resources/threejs/r112/build/three.min.js"></script>
<script src="https://threejsfundamentals.org/threejs/resources/threejs/r112/examples/js/controls/OrbitControls.js"></script>
<canvas id="c"></canvas>

请注意,您可能希望在所有数学运算之前调用 camera.updateMatrixWorld() 以确保目标不会延迟一帧。

如果对象在层次结构中,则还有更多工作要做。您可以计算一下,也可以只将对象附加到场景,然后将其附加回其在层次结构中的位置

const parent = object.parent;

// move object to scene without changing it's world orientation
scene.attach(object);

// do stuff above

// move object to parent without changing it's world orientation
parent.attach(object);

关于Three.js 将对象移动到相机前面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59638065/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com