Three.js如何计算3DObject的2D包围框?

在这里插入图片描述

推荐:用 NSDT编辑器 快速搭建可编程3D场景

在Three.js应用开发中,有时你可能需要为3D场景中的网格绘制2D的包围框,应该怎么做?

朴素的想法是把网格的3D包围框投影到屏幕空间,例如,下图中的绿色框 3D包围框, 当将其投影为 2D 时,得到的红色2D包围框,显然比想要的蓝色框大很多:
在这里插入图片描述

正确的做法是先将3D网格投影到屏幕空间,再计算2D包围框。

1、计算单个网格的2D包围框

只需将所有顶点转换为屏幕空间并从中创建一个 2d 边界框:

function computescreenspaceboundingbox(mesh, camera) {var vertices = mesh.geometry.vertices;var vertex = new three.vector3();var min = new three.vector3(1, 1, 1);var max = new three.vector3(-1, -1, -1);for (var i = 0; i < vertices.length; i++) {var vertexworldcoord = vertex.copy(vertices[i]).applymatrix4(mesh.matrixworld);var vertexscreenspace = vertexworldcoord.project(camera);min.min(vertexscreenspace);max.max(vertexscreenspace);}return new three.box2(min, max);
}

生成的 box2 位于标准化屏幕坐标 [-1, 1] 中, 可以通过乘以渲染器高度和宽度的一半来获得像素:

function normalizedtopixels(coord, renderwidthpixels, renderheightpixels) {var halfscreen = new three.vector2(renderwidthpixels/2, renderheightpixels/2)return coord.clone().multiply(halfscreen);
}

2、计算3DObject的2D包围框

更完善的实现需要考虑组、子节点等各种3DObject,其中可能包含多个网格,这需要一个递归实现,代码如下:

function computescreenspaceboundingbox(obj, camera) {var min;var max;// is this an array of objects?if(array.isarray(obj)) {for(var i = 0; i < obj.length; ++i) {let box2 = computescreenspaceboundingbox(obj[i], camera);if(min === undefined) {min = box2.min.clone();max = box2.max.clone();} else {min.min(box2.min);max.max(box2.max);}}}// does this object have geometry?if(obj.geometry !== undefined) {var vertices = obj.geometry.vertices;if(vertices === undefined&& obj.geometry.attributes !== undefined&& 'position' in obj.geometry.attributes) {// buffered geometryvar vertex = new three.vector3();       var pos = obj.geometry.attributes.position;for(var i = 0; i < pos.count * pos.itemsize; i += pos.itemsize){vertex.set(pos.array[i], pos.array[i + 1], pos.array[1 + 2]);var vertexworldcoord = vertex.applymatrix4(obj.matrixworld);var vertexscreenspace = vertexworldcoord.project(camera);if(min === undefined) {min = vertexscreenspace.clone();max = vertexscreenspace.clone();}min.min(vertexscreenspace);max.max(vertexscreenspace);}} else {// regular geometryvar vertex = new three.vector3();       for(var i = 0; i < vertices.length; ++i) {var vertexworldcoord = vertex.copy(vertices[i]).applymatrix4(obj.matrixworld);var vertexscreenspace = vertexworldcoord.project(camera);if(min === undefined) {min = vertexscreenspace.clone();max = vertexscreenspace.clone();}min.min(vertexscreenspace);max.max(vertexscreenspace);}}}// does this object have children?if(obj.children !== undefined) {for(var i = 0; i < obj.children.length; ++i) {let box2 = computescreenspaceboundingbox(obj.children[i], camera);if(min === undefined) {min = box2.min.clone();max = box2.max.clone();} else {min.min(box2.min);max.max(box2.max);}}}return new three.box2(min, max);
}

原文链接:计算3D对象的2D包围框 — BimAnt

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/130827.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LeetCode【84】柱状图中的最大矩形

题目&#xff1a; 思路&#xff1a; https://blog.csdn.net/qq_28468707/article/details/103682528 https://www.jianshu.com/p/2b9a36a548fa 清晰 代码&#xff1a; public int largestRectangleArea(int[] heights) {int[] heightadd new int[heights.length 1];for (i…

php+html+js+ajax实现文件上传

phphtmljsajax实现文件上传 目录 一、表单单文件上传 1、上传页面 2、接受文件上传php 二、表单多文件上传 1、上传页面 2、接受文件上传php 三、表单异步xhr文件上传 1、上传页面 2、接受文件上传php 四、表单异步ajax文件上传 1、上传页面 2、接受文件上传ph…

typora常用偏好设置

启用自动保存 关闭拼写检查 插入图片的设置 将图片保存在当前文件夹内 换行设置 关闭换行符的显示功能

ElementUI增删改的实现及表单验证

文章目录 一、准备二、添加功能2.1 新增添加按钮2.2 添加弹出框2.3 data中添加内容2.4 methods中添加相关方法 三、编辑功能3.1 表格中添加编辑和删除按钮3.2 methods中添加方法3.3 修改methods中clear方法3.4 修改methods中的handleSubmit方法 四、删除书籍功能4.1 往methods的…

【LeetCode刷题笔记】哈希查找

771. 宝石与石头 解题思路&#xff1a; 1. HashSet &#xff0c;把所有 宝石 加入 set , 然后遍历检查 每一块石头是否包含在set中 &#xff0c;若包含就是宝石。 2. 计数数组map, 把所有 宝石 进行 count 数组 计数 &#xff0c;, 然后遍历检查 每一块石头是否 count[stone] …

算法错题簿(持续更新)

自用算法错题簿&#xff0c;按算法与数据结构分类 python1、二维矩阵&#xff1a;记忆化搜索dp2、图论&#xff1a;DFS3、回溯&#xff1a;129612964、二叉树&#xff1a;贪心算法5、字符串&#xff1a;记忆化搜索6、01字符串反转&#xff1a;结论题7、二进制数&#xff1a;逆向…

高效节能双冷源空调架构在某新建数据中心项目中的应用

随着互联网、通信、金融等行业的发展&#xff0c;数据中心产业迈入高质量发展新阶段&#xff0c;在国家“双碳”战略目标和“东数西算”工程的有力指引下&#xff0c;数据中心加快向创新技术、强大算力、超高能效为特征的方向演进。数据中心已经成为支撑经济社会数字化转型必不…

Linux系统管理:虚拟机Centos Stream 9安装

目录 一、理论 1.Centos Stream 9 二、实验 1.虚拟机Centos Stream 9安装准备阶段 2.安装Centos Stream 9 3.进入系统 一、理论 1.Centos Stream 9 (1) 简介 CentOS Stream 是一种 Linux 操作系统。安装此操作系统的难题在于&#xff0c;在安装此系统之前&#xff0c…

想要用Chat GPT写申请文书?先看各大名校招生官对它的态度是什么?

新的申请季已经正式开始&#xff0c;一些热门项目的ED截止日期也不再遥远&#xff0c;因此很多准留学生们都已经开始了关于文书的创作。 而随着科技的不断发展&#xff0c;以ChatGPT为首的一众AI工具也作为一种辅助手段愈发融入了我们的生活。 那么不免就会有一些同学在准备申…

户外led显示屏中的裸眼3D效果是怎么做出来的?

近几年&#xff0c;裸眼3D成了一个热点词汇&#xff0c;但凡它出现的地方都会迅速成为网络热门话题和网红打卡点。裸眼3D大屏凭借其立体逼真的画面显示效果&#xff0c;带给人们新颖震撼的视觉体验&#xff0c;不仅成为户外广告的“新宠”&#xff0c;还成为了城市的新地标&…

Java 获取服务器资源(内存、负载、磁盘容量)

1.说明 我们经常通过SSH终端发送shell命令进行服务器运维&#xff0c;从而获取到服务器的各种资源&#xff0c;按照这个思路&#xff0c;我们可以利用Java做一个定时任务&#xff0c;定时采集服务器资源使用情况&#xff0c;从而实现服务器资源的动态呈现。 2.封装SSH操作方法…

若依微服务前后端部署启动流程(只记录)

若依官网&#xff1a;https://www.ruoyi.vip/ 若依源码下载&#xff0c;直接zip既可&#xff1a;RuoYi-Cloud: &#x1f389; 基于Spring Boot、Spring Cloud & Alibaba的分布式微服务架构权限管理系统&#xff0c;同时提供了 Vue3 的版本 下载解压&#xff0c;导入 idea&…