WEB 3D技术 three.js 多元素包围盒

本文 我们说多个物体的包围盒

我们先编写如下代码

import './style.css'
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";

const scene = new THREE.Scene();
const sphere1 =new THREE .Mesh(
    new THREE.SphereGeometry(0.7, 32, 32),
    new THREE.MeshBasicMaterial({
        color: 0x00FF00
    })
)
sphere1.position.x = -3;
scene.add(sphere1);

const sphere2 = new THREE .Mesh(
    new THREE.SphereGeometry(0.7, 32, 32),
    new THREE.MeshBasicMaterial({
        color: 0x0000FF
    })
)
scene.add(sphere2);

const sphere3 = new THREE .Mesh(
    new THREE.SphereGeometry(0.7, 32, 32),
    new THREE.MeshBasicMaterial({
        color:  0xFFE0FF
    })
)
sphere3.position.x = 3;
scene.add(sphere3);

//创建相机
const camera = new THREE.PerspectiveCamera(
    45, //视角 视角越大  能看到的范围就越大
    window.innerWidth / window.innerHeight,//相机的宽高比  一般和画布一样大最好
    0.1,  //近平面  相机能看到最近的距离
    1000  //远平面  相机能看到最远的距离
);

//c创建一个canvas容器  并追加到 body上
const renderer = new THREE.WebGLRenderer(0);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

//设置相机位置   这里 我们设置Z轴  大家可以试试  S Y 和 Z  都是可以的
camera.position.z = 5;
//设置相机默认看向哪里   三个 0  代表 默认看向原点
camera.lookAt(0, 0, 0);
//将内容渲染到元素上
renderer.render(scene, camera);
const controls = new OrbitControls(camera, renderer.domElement);

function animate() {
    controls.update();
    requestAnimationFrame(animate);
    /*cube.rotation.x += 0.01;
    cube.rotation.y += 0.01;*/
    renderer.render(scene, camera);
}
animate();

先写出三个物体
WEB 3D技术 three.js 多元素包围盒_第1张图片
觉得阐述为 我们要遍历 拿到每一个元素的包围盒 然后将他们合并为一个大的包围盒

我们先官网搜索 box3
如下图所示 有一个 union
WEB 3D技术 three.js 多元素包围盒_第2张图片
它可以将多个盒子合并计算 最后得到一个合并后的大盒子

目前 代码的话 我们是三个小球 都添加到了场景中
WEB 3D技术 three.js 多元素包围盒_第3张图片
我们可以遍历场景中的子元素

for(let i = 0;i < scene.children.length;i++) {
    console.log(scene.children[i]);
}

WEB 3D技术 three.js 多元素包围盒_第4张图片
运行之后 我们查看控制台
WEB 3D技术 three.js 多元素包围盒_第5张图片
我们可以这样写

//创建一个盒子
var box = new THREE.Box3();
for(let i = 0;i < scene.children.length;i++) {
    //确保元素具有几何体属性
    if(scene.children[i].geometry) {
        //通过 computeBoundingBox 计算当前元素的包围盒
        scene.children[i].geometry.computeBoundingBox();
        //获取当前元素的包围盒
        let box3 = scene.children[i].geometry.boundingBox;
        scene.children[i].updateMatrixWorld(true,true)
        // 将包围盘转换到世界坐标系
        box3.applyMatrix4(scene.children[i].matrixWorld);
        //通过外面的盒子 合并包围盒
        box.union(box3);
    }
}
//创建包围盒辅助器
let boxHelper = new THREE.Box3Helper(box, 0xffff00);
//将包围盒添加到场景中
scene.add(boxHelper);

先创建一个 盒子 叫box 后面的包围盒 用它来创建
遍历 scene.children 我们只要里面的盒子元素 所以 判断 要有geometry字段才继续
然后computeBoundingBox计算出包围盒属性 然后通过boundingBox字段拿到包围盒属性
updateMatrixWorld applyMatrix4套餐 做一个更新世界举证 元素移动时需要这个处理
然后 通过 union 将每一次算出的结果 都合并到 我们最开始创建的 box 盒子中
Box3Helper 通过 box 盒子创建包围盒辅助器 然后加入世界坐标
运行结果如下
WEB 3D技术 three.js 多元素包围盒_第6张图片
我们转过来 看清楚一点
WEB 3D技术 three.js 多元素包围盒_第7张图片
其实还有另一种方式
而且只需要一行代码

//创建一个盒子
var box = new THREE.Box3();
for(let i = 0;i < scene.children.length;i++) {
    //确保元素具有几何体属性
    if(scene.children[i].geometry) {
        let box3 = new THREE.Box3().setFromObject(scene.children[i]);
        box.union(box3);
    }
}
//创建包围盒辅助器
let boxHelper = new THREE.Box3Helper(box, 0xffff00);
//将包围盒添加到场景中
scene.add(boxHelper);

setFromObject 能够直接帮你算好并返回包围盒 且有更新矫正的功能
WEB 3D技术 three.js 多元素包围盒_第8张图片

你可能感兴趣的:(前端,3d,javascript)