WEB 3D技术 three.js 包围盒

2024-01-06 19:36
文章标签 技术 web js 3d 包围 three

本文主要是介绍WEB 3D技术 three.js 包围盒,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本文 我们来说 包围盒

如下图所示 就是一个方框 框住我们整个物体
在这里插入图片描述
它的作用 比较明显的就是 当用户点击某个物体 我们用包围盒套住 用户能够很直观的知道自己当前选中的物体是哪一个
还有就是 比如 我们物体做的比较复杂 是非常多顶点构建的 那么 我们判断它有没有和其他物体接触就很麻烦 但 有了包围盒 我们只需要判断包围盒有没有接触即可

然后 我们官网搜索 BufferGeometry
在这里插入图片描述
包围盒是所有几何体都有的属性

这里 我们有两个 一个是 包围盒 另一个是 包围圈
简单说 一个是包围成立方体 另一个是成球形包围
在这里插入图片描述
默认情况 例如我们自己创建的几何体 是不会有这个属性的 我们需要自己通过 computeBoundingBox 去计算
在这里插入图片描述
我这里 先写成这样的代码

import './style.css'
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
import { RGBELoader } from "three/examples/jsm/loaders/RGBELoader.js";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";//创建相机
const camera = new THREE.PerspectiveCamera(45, //视角 视角越大  能看到的范围就越大window.innerWidth / window.innerHeight,//相机的宽高比  一般和画布一样大最好0.1,1000
);
const scene = new THREE.Scene();const gltfLoader = new GLTFLoader();
gltfLoader.load(// 模型路径"/gltf/scene.gltf",// 加较完成同调(gltf) =>{gltf.scene.traverse((child) => {if (child.isMesh) {child.frustumCulled = false;child.castShadow = true;child.material.emissive = child.material.color;child.material.emissiveMap = child.material.map;}});scene.add(gltf.scene);}
)//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);let rgbeloader = new RGBELoader();
rgbeloader.load("/xhdr/Alex_Hart-Snow_Pano_2k.hdr",(texture) =>{scene.background = texture;texture.mapping = THREE.EquirectangularReflectionMapping;
})function animate() {controls.update();requestAnimationFrame(animate);/*cube.rotation.x += 0.01;cube.rotation.y += 0.01;*/renderer.render(scene, camera);
}
animate();

这里 就是简单引入了 hdr场景贴图 和一个 glb 车的3D元素
在这里插入图片描述
那么 现在 我们要给这台车 做一个包围盒

首先 我们需要拿到它的几何体对象 先在代码中 控制台打印gltf对象下面的 scene
在这里插入图片描述
然后 下面有两个比较重要的内容 它的name 和 id
在这里插入图片描述
getObjectById 通过id获取元素对象
getObjectByName 通过name属性获取元素对象
我们肯定是用name 会更方便一点

我们的name 叫 webvrmodel_Scene
我们改写代码如下

const gltfLoader = new GLTFLoader();
gltfLoader.load(// 模型路径"/gltf/scene.gltf",// 加较完成同调(gltf) =>{gltf.scene.traverse((child) => {if (child.isMesh) {child.frustumCulled = false;child.castShadow = true;child.material.emissive = child.material.color;child.material.emissiveMap = child.material.map;}});scene.add(gltf.scene);let webvrmodel = gltf.scene.getObjectByName("webvrmodel_Scene");console.log(webvrmodel);}
)

通过 getObjectByName 寻找name 为 webvrmodel_Scene的对象
然后 下面用console.log 输出在控制台上

运行结果如下
在这里插入图片描述
这里 虽然拿到了 但其实 我们也不需要这么麻烦
可以直接这样改

const gltfLoader = new GLTFLoader();
gltfLoader.load("/gltf/scene.gltf",(gltf) => {gltf.scene.traverse((child) => {if (child.isMesh) {child.frustumCulled = false;child.castShadow = true;child.material.emissive = child.material.color;child.material.emissiveMap = child.material.map;const geometry = child.geometry;geometry.computeBoundingBox()let duckBox = geometry.boundingBox;console.log(duckBox);}});scene.add(gltf.scene);}
);

拿到 geometry 几何体对象字段
然后 通过对象 调用 computeBoundingBox计算出 包围盒对象
然后 通过 geometry.boundingBox 获取他的包围盒对象 并在控制台打印
这里正常的几何体对象都可以调用computeBoundingBox 取 boundingBox
是因为 我们这是导入的gltf资源 所以还要想办法去拿这个几何体的对象

运行如下
在这里插入图片描述
包围盒对象 给了两个属性 max和min
两个三维向量 但是 两个形成一个包围盒 这是为什么呢?

它的两个向量 其实就是两个点的坐标
因为 他是一个很规整的立方体 包围盒 所以 它只需要如下图的两位点的位置 就可以拉出一个立方体
在这里插入图片描述
那么 既然已经拿到最小和最大两个值 那么 我们就可以拉出这样一个包围盒工具
我们可以将代码改成这样

const gltfLoader = new GLTFLoader();
gltfLoader.load("/gltf/scene.gltf",(gltf) => {gltf.scene.traverse((child) => {if (child.isMesh) {child.frustumCulled = false;child.castShadow = true;child.material.emissive = child.material.color;child.material.emissiveMap = child.material.map;const geometry = child.geometry;geometry.computeBoundingBox()let boxHelper = new THREE.Box3Helper(geometry.boundingBox, 0xffff00);scene.add(boxHelper);}});scene.add(gltf.scene);}
);

THREE.Box3Helper 需要两个参数 第一个是 需要处理的包围盒对象 就是我们从gltf几何体对象上拿到的 boundingBox属性 第二个为一个颜色属性
然后将这个包围盒对象 add到场景中

运行代码如下
在这里插入图片描述
我们外面这个包围盒的线就出来了

几何体 则更简单 我们编写代码如下

import './style.css'
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
import { RGBELoader } from "three/examples/jsm/loaders/RGBELoader.js";
//创建相机
const camera = new THREE.PerspectiveCamera(45, //视角 视角越大  能看到的范围就越大window.innerWidth / window.innerHeight,//相机的宽高比  一般和画布一样大最好0.1,1000
);
const scene = new THREE.Scene();
let uvTexture = new THREE.TextureLoader().load("/textUv.jpg");const geometry = new THREE.BufferGeometry();
// 创建顶点数据
const vertices = new Float32Array([-1.0,-1.0 ,0.0,1.0 ,-1.0, 0.0,1.0 ,1.0 ,0.0,-1.0 ,1.0, 0.0
])
geometry.setAttribute("position", new THREE.BufferAttribute(vertices, 3));
const indices = new Uint16Array([0 ,1 ,2, 0, 3, 2]);
const material = new THREE.MeshBasicMaterial({map: uvTexture,side: THREE.DoubleSide
})
const uv = new Float32Array([0, 0, 1, 0, 1, 1, 0, 1
])
geometry.setAttribute("uv", new THREE.BufferAttribute(uv, 2));
const normals = new Float32Array([0, 0, 1,0, 0, 1,0, 0, 1,0, 0, 1
])
geometry.setAttribute("normal", new THREE.BufferAttribute(normals, 3));
geometry.setIndex(new THREE.BufferAttribute(indices, 1));
console.log(geometry);
const cube = new THREE.Mesh(geometry, material);
scene.add(cube)//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);let rgbeloader = new RGBELoader();
rgbeloader.load("/xhdr/Alex_Hart-Snow_Pano_2k.hdr",(texture) =>{scene.background = texture;texture.mapping = THREE.EquirectangularReflectionMapping;material.envMap = texture;
})function animate() {controls.update();requestAnimationFrame(animate);/*cube.rotation.x += 0.01;cube.rotation.y += 0.01;*/renderer.render(scene, camera);
}
animate();

在这里插入图片描述
然后添加代码

geometry.computeBoundingBox()
let boxHelper = new THREE.Box3Helper(geometry.boundingBox, 0xffff00);
scene.add(boxHelper);

在这里插入图片描述
我们外面的包围盒就出来了
在这里插入图片描述

这篇关于WEB 3D技术 three.js 包围盒的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/577382

相关文章

Spring常见错误之Web嵌套对象校验失效解决办法

《Spring常见错误之Web嵌套对象校验失效解决办法》:本文主要介绍Spring常见错误之Web嵌套对象校验失效解决的相关资料,通过在Phone对象上添加@Valid注解,问题得以解决,需要的朋... 目录问题复现案例解析问题修正总结  问题复现当开发一个学籍管理系统时,我们会提供了一个 API 接口去

使用IntelliJ IDEA创建简单的Java Web项目完整步骤

《使用IntelliJIDEA创建简单的JavaWeb项目完整步骤》:本文主要介绍如何使用IntelliJIDEA创建一个简单的JavaWeb项目,实现登录、注册和查看用户列表功能,使用Se... 目录前置准备项目功能实现步骤1. 创建项目2. 配置 Tomcat3. 项目文件结构4. 创建数据库和表5.

Node.js 中 http 模块的深度剖析与实战应用小结

《Node.js中http模块的深度剖析与实战应用小结》本文详细介绍了Node.js中的http模块,从创建HTTP服务器、处理请求与响应,到获取请求参数,每个环节都通过代码示例进行解析,旨在帮... 目录Node.js 中 http 模块的深度剖析与实战应用一、引言二、创建 HTTP 服务器:基石搭建(一

手把手教你idea中创建一个javaweb(webapp)项目详细图文教程

《手把手教你idea中创建一个javaweb(webapp)项目详细图文教程》:本文主要介绍如何使用IntelliJIDEA创建一个Maven项目,并配置Tomcat服务器进行运行,过程包括创建... 1.启动idea2.创建项目模板点击项目-新建项目-选择maven,显示如下页面输入项目名称,选择

使用Vue.js报错:ReferenceError: “Vue is not defined“ 的原因与解决方案

《使用Vue.js报错:ReferenceError:“Vueisnotdefined“的原因与解决方案》在前端开发中,ReferenceError:Vueisnotdefined是一个常见... 目录一、错误描述二、错误成因分析三、解决方案1. 检查 vue.js 的引入方式2. 验证 npm 安装3.

JS常用组件收集

收集了一些平时遇到的前端比较优秀的组件,方便以后开发的时候查找!!! 函数工具: Lodash 页面固定: stickUp、jQuery.Pin 轮播: unslider、swiper 开关: switch 复选框: icheck 气泡: grumble 隐藏元素: Headroom

无人叉车3d激光slam多房间建图定位异常处理方案-墙体画线地图切分方案

墙体画线地图切分方案 针对问题:墙体两侧特征混淆误匹配,导致建图和定位偏差,表现为过门跳变、外月台走歪等 ·解决思路:预期的根治方案IGICP需要较长时间完成上线,先使用切分地图的工程化方案,即墙体两侧切分为不同地图,在某一侧只使用该侧地图进行定位 方案思路 切分原理:切分地图基于关键帧位置,而非点云。 理论基础:光照是直线的,一帧点云必定只能照射到墙的一侧,无法同时照到两侧实践考虑:关

【专题】2024飞行汽车技术全景报告合集PDF分享(附原数据表)

原文链接: https://tecdat.cn/?p=37628 6月16日,小鹏汇天旅航者X2在北京大兴国际机场临空经济区完成首飞,这也是小鹏汇天的产品在京津冀地区进行的首次飞行。小鹏汇天方面还表示,公司准备量产,并计划今年四季度开启预售小鹏汇天分体式飞行汽车,探索分体式飞行汽车城际通勤。阅读原文,获取专题报告合集全文,解锁文末271份飞行汽车相关行业研究报告。 据悉,业内人士对飞行汽车行业

在JS中的设计模式的单例模式、策略模式、代理模式、原型模式浅讲

1. 单例模式(Singleton Pattern) 确保一个类只有一个实例,并提供一个全局访问点。 示例代码: class Singleton {constructor() {if (Singleton.instance) {return Singleton.instance;}Singleton.instance = this;this.data = [];}addData(value)

Java Web指的是什么

Java Web指的是使用Java技术进行Web开发的一种方式。Java在Web开发领域有着广泛的应用,主要通过Java EE(Enterprise Edition)平台来实现。  主要特点和技术包括: 1. Servlets和JSP:     Servlets 是Java编写的服务器端程序,用于处理客户端请求和生成动态网页内容。     JSP(JavaServer Pages)