three.js实现多个模型在一个固定大小的平面自动布局功能代码
时间: 2023-11-27 09:49:42 浏览: 147
以下是一个简单的实现多个模型自动布局在一个平面上的示例代码,使用了Three.js中的OrbitControls和Raycaster:
```javascript
// 初始化场景、相机、渲染器
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
var renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// 添加轨道控制器
var controls = new THREE.OrbitControls(camera, renderer.domElement);
// 添加平面
var planeGeometry = new THREE.PlaneBufferGeometry(10, 10);
var planeMaterial = new THREE.MeshBasicMaterial({ color: 0xcccccc, side: THREE.DoubleSide });
var plane = new THREE.Mesh(planeGeometry, planeMaterial);
plane.rotation.x = -Math.PI / 2;
scene.add(plane);
// 添加多个模型
var models = [];
var loader = new THREE.GLTFLoader();
loader.load('model1.glb', function (gltf) {
var model = gltf.scene;
scene.add(model);
models.push(model);
});
loader.load('model2.glb', function (gltf) {
var model = gltf.scene;
scene.add(model);
models.push(model);
});
// 布局模型
var layout = function () {
var size = 1.5; // 模型之间的间隔
var row = 0, col = 0;
for (var i = 0; i < models.length; i++) {
var model = models[i];
model.position.set(col * size, 0, row * size);
col++;
if (col > 2) {
row++;
col = 0;
}
}
};
// 窗口大小变化时重新计算相机和渲染器的大小
window.addEventListener('resize', function () {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}, false);
// 渲染循环
var animate = function () {
requestAnimationFrame(animate);
controls.update();
renderer.render(scene, camera);
};
animate();
// 监听鼠标点击事件,获取模型信息
var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
window.addEventListener('click', function (event) {
// 计算鼠标点击位置
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
// 从相机发射一条射线,检测是否与模型相交
raycaster.setFromCamera(mouse, camera);
var intersects = raycaster.intersectObjects(models);
// 如果有相交的模型,输出模型名称
if (intersects.length > 0) {
console.log(intersects[0].object.name);
}
}, false);
// 在模型加载完成后自动布局
loader.manager.onLoad = function () {
layout();
};
```
这个示例将两个GLTF模型加载到场景中,并将它们布局在一个10x10的平面上。当窗口大小改变时,相机和渲染器也会自适应调整大小。当鼠标点击一个模型时,控制台会输出模型名称。模型布局的函数是`layout()`,它将每个模型按行列布局,并设置它们的位置。
阅读全文