gpt4 book ai didi

three.js - 三是 - 如何在 OrbitControls 中为 OrthographicCamera 限制平移,以便对象(纹理图像)始终在场景中

转载 作者:行者123 更新时间:2023-12-02 02:47:16 25 4
gpt4 key购买 nike

我正在使用 OrbitControls 来控制正交相机。该场景具有 2d 纹理图像。

当到达图像边缘时,我想限制相机的平移。
例如,当摄像机向左平移,在 View 窗口中图像向右平移时,当图像的左边缘在可见窗口的右侧时,停止向左平移(见附图) )
enter image description here

Herehere平移限制是硬编码的,但在我的情况下,限制取决于缩放(我假设这也取决于图像的大小)。例如,当图像一直向左移动时,

放大时,scope.target.x ~= ~100

缩小时,scope.target.x ~= ~800

当图像的左侧到达可见窗口的左边缘时,如何禁用向左平移?

谢谢,
阿夫纳

编辑:

@Rabbid76 感谢您的建议。通过对示例代码进行一些修改,我解决了问题,即图像始终覆盖 View 窗口。
here详情

最佳答案

您可以手动限制平底锅。

假设您有一个 OrthographicCamera ,它看着 xy 平面。

例如

camera = new THREE.OrthographicCamera(-5*aspect, 5*aspect, -5, 5, -100, 100);
camera.position.set(0, 0, -1);

你有一个网格( object ),从中你可以得到边界框( THREE.Box3 ):

var bbox = new THREE.Box3().setFromObject(object);

有了这些信息,可以计算物体的最小和最大 x 和 y 坐标:

var min_x = camera.left  - bbox.min.x;
var max_x = camera.right - bbox.max.x;
var min_y = camera.top - bbox.min.y;
var max_y = camera.bottom - bbox.max.y;

当前相机位置和目标可以被钳制在限制范围内:

let pos_x =  Math.min(max_x, Math.max(min_x, camera.position.x));
let pos_y = Math.min(max_y, Math.max(min_y, camera.position.y));

更新 OrthographicCamera OrbitControls :

camera.position.set(pos_x, pos_y, camera.position.z);
camera.lookAt(pos_x, pos_y, orbitControls.target.z);

orbitControls.target.x = pos_x;
orbitControls.target.y = pos_y;
orbitControls.update();

看例子:

(function onLoad() {
var container, loader, camera, scene, renderer, orbitControls, object, bbox;

init();
animate();

function init() {
container = document.getElementById('container');

renderer = new THREE.WebGLRenderer({
antialias: true,
alpha: true
});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
container.appendChild(renderer.domElement);

aspect = window.innerWidth / window.innerHeight;
camera = new THREE.OrthographicCamera(-5*aspect, 5*aspect, -5, 5, -100, 100);
camera.position.set(0, 0, -1);

loader = new THREE.TextureLoader();
loader.setCrossOrigin("");

scene = new THREE.Scene();
scene.background = new THREE.Color(0xffffff);
scene.add(camera);
window.onresize = resize;

orbitControls = new THREE.OrbitControls(camera);

orbitControls.enabled = true;
orbitControls.enableRotate = false;
orbitControls.screenSpacePanning = true;
orbitControls.mouseButtons = {
LEFT: THREE.MOUSE.RIGHT,
MIDDLE: THREE.MOUSE.MIDDLE,
RIGHT: THREE.MOUSE.LEFT
}


addGridHelper();
createModel();

}

function createModel() {

var material = new THREE.MeshBasicMaterial({color:'#ff4040'});
var geometry = new THREE.BoxGeometry( 1, 1, 1 );

object = new THREE.Mesh(geometry, material);
bbox = new THREE.Box3().setFromObject(object);

scene.add(object);
}

function addGridHelper() {

var helper = new THREE.GridHelper(100, 100);
helper.rotation.x = Math.PI / 2;
helper.material.opacity = 0.25;
helper.material.transparent = true;
scene.add(helper);

var axis = new THREE.AxesHelper(1000);
scene.add(axis);
}

function resize() {

var aspect = window.innerWidth / window.innerHeight;
renderer.setSize(window.innerWidth, window.innerHeight);
camera.left = -5*aspect;
camera.right = 5*aspect;
camera.updateProjectionMatrix();
}

function animate() {
requestAnimationFrame(animate);

var min_x = camera.left - bbox.min.x;
var max_x = camera.right - bbox.max.x;
var min_y = camera.top - bbox.min.y;
var max_y = camera.bottom - bbox.max.y;

let pos_x = Math.min(max_x, Math.max(min_x, camera.position.x));
let pos_y = Math.min(max_y, Math.max(min_y, camera.position.y));

camera.position.set(pos_x, pos_y, camera.position.z);
camera.lookAt(pos_x, pos_y, orbitControls.target.z);

orbitControls.target.x = pos_x;
orbitControls.target.y = pos_y;
orbitControls.update();

render();
}

function render() {
renderer.render(scene, camera);
}
})();
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/99/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<div id="container"></div>

关于three.js - 三是 - 如何在 OrbitControls 中为 OrthographicCamera 限制平移,以便对象(纹理图像)始终在场景中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53902665/

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