VUE3使用three.js显示3D模型

   使用3D模型作为自动化系统的界面已经成为潮流。尽管在AutomationML 中推荐COLLADA作为 3D 模型的标准。但是COLLADA的开发者khronos 集团却已经开发了COLLADA的后继者glTF 。glTF 2.0已经成为国际标准ISO/IEC 12113:2022。

      Khronos声称-‘glTF是3D里的JPEG’。目前看来glTF 更加流行。

glTF 概述

glTF 的工业中的应用

CAD 软件的支持

solidworks 2020版 开始支持glTF 的导出。

3D 查看器

windows 上有一个3D查看器,可以显示导出的glTF 3D模型

支持glTF 的3D软件

SketchUp

SketchUp,民间俗称“草图大师”,是全世界极受欢迎的三维建模与设计软件,在全球拥有4千万年度用户。SketchUp在建筑设计、家具设计、展陈设计、电影美术、舞台美术、产品设计、工程设计等领域有广泛的应用。SketchUp由于其简单、易学、灵活等特点,是目前新兴的原生的BIM正向设计工具,尤其在室内装饰、以及其它应用领域。

Blender

   Blender 是一款永久开源免费的 3D 创作软件,支持整个 3D 创作流程:建模、雕刻、骨骼装配、动画、模拟、实时渲染、合成和运动跟踪,甚至可用作视频编辑及游戏创建。

Web 前端的支持

Web 前端有一个功能强大的3D 开源库Three.js 支持glTF 的导入。Three.JS 的背后是webGL 技术

   WebGL可以为HTML5 Canvas提供硬件3D加速渲染(部分计算GPU),它借助系统显卡来在浏览器里更流畅地展示3D场景和模型了,还能创建复杂的导航和数据视觉化。WebGL的本质 - JavaScript操作OpenGL接口。

        Three.js 是一款 webGL(3D绘图标准,在此不赘述)引擎,可以运行于所有支持 webGL 的浏览器。Three.js 封装了 webGL 底层的 API ,为我们提供了高级的开发接口,可以使用简单的代码去实现 3D 渲染。

       Three.js 支持glTF 文件的导入。

VUE3+Three.js实验

Step1 安装Three.js

 npm install three --save --force

Step2 代码

首先要对下列参数初始化:

  • 相机 camera
  • 场景 scene
  • 渲染器renderer
  • 控制 controls,
  • 环境光 ambientLight,
  • 方向光 directionalLight

渲染器设置事件处理,实现点击对象的操作(OnClick)
遇到的问题

  • 物体显示不出来,主要是导入glTF 时model.scale.set(2500, 2500, 2500)缩放比例太小了
  • 物体无法通过鼠标旋转,缩放。最后发现是没有设置相机的位置。

           camera.position.set(20, 30, 20);

<script  setup>
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
import { ref, onMounted } from "vue";
let screenDom = ref();
var camera,scene,renderer,controls,ambientLight,directionalLight
onMounted(() => {scene = new THREE.Scene();// 创建相机camera = new THREE.PerspectiveCamera(135,screenDom.value.clientWidth / screenDom.value.clientHeight,0.1,100);camera.position.set(20, 30, 20); //important// 添加环境光ambientLight = new THREE.AmbientLight(0xffffff, 0.9);scene.add(ambientLight);//directionalLight = new THREE.DirectionalLight(0xffffff, 0.8); //光源,color:灯光颜色,intensity:光照强度directionalLight.position.set(400, 200, 300);scene.add(directionalLight);// 创建渲染器renderer = new THREE.WebGLRenderer({ antialias: true });renderer.setClearColor(new THREE.Color("#000000"));renderer.setSize(screenDom.value.clientWidth, screenDom.value.clientHeight);renderer.domElement.addEventListener("click", onClick, false);screenDom.value.appendChild(renderer.domElement);//controls = new OrbitControls(camera, renderer.domElement);controls.enableDamping = true;controls.enablePan = true;controls.enableZoom = true;controls.autoRotate = true;controls.autoRotateSpeed = 9;controls.update(); //重新设置轨道,相当于刷新//添加模型const loader = new GLTFLoader();loader.load("../../../public/Glasses-v1.glb",(gltf) => {// 加载成功后的回调函数const model = gltf.scene;model.scale.set(2500, 2500, 2500); // 缩放模型const box = new THREE.Box3().setFromObject(model);const center = box.getCenter(new THREE.Vector3());let axis = new THREE.Vector3(0, 1, 0);model.rotateOnAxis(axis, Math.PI * 2);model.position.sub(center); // 将模型位置移到原点处scene.add(model);},(xhr) => {// 加载过程中的回调函数console.log((xhr.loaded / xhr.total) * 100 + "% loaded");},(error) => {// 加载失败的回调函数console.error("Failed to load model", error);});// 渲染场景const render = () => {renderer.render(scene, camera);controls.update();requestAnimationFrame(render);};render();
});
function onClick() {event.preventDefault();const mouse = new THREE.Vector2();const rect = screenDom.value.getBoundingClientRect()mouse.x = ((event.clientX+rect.left) / window.innerWidth) * 2 - 1;mouse.y = -((event.clientY+rect.top)/ window.innerHeight) * 2 + 1;console.log("x:"+mouse.x,"y:"+mouse.y);const raycaster = new THREE.Raycaster();raycaster.setFromCamera(mouse, camera);var intersects = raycaster.intersectObjects(scene.children); //arrayif (intersects.length > 0) {var selectedObject = intersects[0];alert(selectedObject.object.name);}
}
</script>
<template><div class="container"><h2>3D 模型</h2><div class="canvas-container" ref="screenDom"></div></div>
</template>
<style scoped>
.canvas-container {width: 800px;height: 400px;
}
body {overflow: hidden;margin: 0px;
}
</style>

最终的界面

小结

        开放自动化是一个热门话题,笔者常常想,开放自动化系统的本质是什么?我认为它们本质是使用公共技术实现的系统。其中包括协议,模型的格式和设计工具。并不一定拘泥于某一种单一的技术或者标准,在AI 时代更是如此,只要是公开的技术就能够转换。大胆地使用IT的新技术,解决自动化行业的问题是当下最重要的。

   

    

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

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

相关文章

Java WEB面试系列-01

1. 什么是 Servlet? Servlet是用Java编写的服务器端程序, 其主要功能在于交互式地浏览和修改数据,生成动态Web内容。 狭义的Servlet是指Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet接口的类,一般情况下,我们一般将Servlet理解为后者。 2. 为什么要使…

问题慢慢解决-通过android emulator调试android kernel-内核条件断点遇到的问题和临时解决方案

起因 在摸索到这个方案之后&#xff0c;mac m1调试aarch64 android kernel最终方案&#xff0c;就准备调试内核了&#xff0c;预备下断点的地方是 b binder_poll b ep_ptable_queue_proc b remove_wait_queue但是由于是android系统&#xff0c;上面三个函数会被频繁的触发&am…

ERC721解读

NFT(非同质化代币):类似于明朝、宋朝的青花瓷。虽然都是青花瓷。但是都具有唯一的典藏价值。而且价值可能不同。 NFT就是具有唯一价值的代币。 ERC721: 是以太坊规定实现NFT的一种标准了。实现ERC21标准的智能合约就是NFT代币了。 1.接口 1.ERC721 定义接口参考&#xff1a;ER…

vue.js中slot插槽的作用

作为一种流行的JavaScript框架&#xff0c;vue.js提供了很多功能强大的特性&#xff0c;其中之一就是插槽&#xff08;slot&#xff09;。插槽是一种能够让父组件向子组件传递内容的机制&#xff0c;它为我们构建可复用的组件提供了更大的灵活性和可扩展性。以下介绍Vue中插槽的…

《Docker极简教程》--Docker服务管理和监控--Docker服务的监控

Docker监控的必要性在于确保容器化环境的稳定性、性能和安全性。以下是几个关键原因&#xff1a; 性能优化和故障排除&#xff1a;监控可以帮助识别容器化应用程序的性能问题&#xff0c;并快速进行故障排除。通过监控关键指标&#xff0c;如CPU利用率、内存使用、网络流量等&…

ElementUI table表格组件实现双击编辑单元格失去焦点还原,支持多单元格

在使用ElementUI table表格组件时有时需要双击单元格显示编辑状态&#xff0c;失去焦点时还原表格显示。 实现思路&#xff1a; 在数据中增加isFocus:false.控制是否显示在table中用cell-dblclick双击方法 先看效果&#xff1a; 上源码&#xff1a;在表格模板中用scope.row…

springboot集成mqtt

文章目录 前言一、MQTT是什么&#xff1f;二、继承步骤1.安装MQTT2.创建项目&#xff0c;引入依赖3. 对应步骤2的代码3 测试 总结mqtt 启动后访问地址 前言 随着物联网的火热,MQTT的应用逐渐增多 曾经也有幸使用过mqtt,今天正好总结下MQTT的使用; 一、MQTT是什么&#xff1f;…

从扩散模型基础到DIT

Diffusion model 扩散模型如何工作&#xff1f; 输入随机噪声和文本内容&#xff0c;通过多次预测并去除图片中的噪声后&#xff0c;最终生成清晰的图像。 以上左边这张图&#xff0c;刚开始是随机噪声&#xff0c;999为时间序列。 为什么不直接预测下一张图片呢&#xff1f;…

springboot+vue的宠物咖啡馆平台(前后端分离)

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

《卓有成效的管理者》

前言 管理工作在很大程度上是要言传身教的&#xff0c;如果管理者不懂得如何在自己的工作中做到卓有成效&#xff0c;就会给其他人树立错误的榜样。 第 1 章 卓有成效是可以学习的 关于体力工作&#xff0c;我们已有一套完整的衡量方法和制度&#xff0c;从工程设计到质量控制…

Java中常用的类(一)

一、API应用程序编程接口&#xff1a; API&#xff1a;指的是官方给开发人员提供的一个说明文档&#xff0c;对于语言有哪些类&#xff0c;类中有哪些方法进行说明 二、Object类 Object是java中所有类的父类&#xff0c;体系结构中最顶层的类&#xff0c;位置是java.lang.Ob…

【深度学习笔记】3_4 逻辑回归之softmax-regression

3.4 softmax回归 Softmax回归&#xff08;Softmax Regression&#xff09;&#xff0c;也称为多类逻辑回归&#xff08;Multinomial Logistic Regression&#xff09;&#xff0c;是一种用于多分类问题的分类算法。虽然名字里面带回归&#xff0c;实际上是分类。 前几节介绍的…

Socks5代理与代理IP的应用

在全球化的背景下&#xff0c;跨界电商和游戏行业正经历着蓬勃发展的时代。然而&#xff0c;随之而来的网络安全挑战也日益突出。为了应对这些挑战&#xff0c;Socks5代理与代理IP等技术成为了保障网络安全的重要工具。本文将探讨这些技术在跨界电商和游戏行业中的应用&#xf…

Python模块百科_时间的访问和转换(time)_下

TOC 一、概述 time模块提供了各种与时间相关的函数。相关功能还可以参阅datetime 和 calendar模块。 尽管所有平台皆可引用此模块&#xff0c;但模块内的函数并不是所有平台都可用。此模块中定义的大多数函数的实现都是调用其所在平台的C语言库的同名函数。因为这些函数的语义…

Rust之构建命令行程序(四):用TDD(测试-驱动-开发)模式来开发库的功能

开发环境 Windows 11Rust 1.75.0 VS Code 1.86.2 项目工程 这次创建了新的工程minigrep. 用测试-驱动模式来开发库的功能 既然我们已经将逻辑提取到src/lib.rs中&#xff0c;并将参数收集和错误处理留在src/main.rs中&#xff0c;那么为代码的核心功能编写测试就容易多了。我…

C#浮点运算出错问题

在计算单价等活动的时候&#xff0c;我们经常会用到double 浮点进行运算&#xff0c;但是在乘除的时候经常出现精度丢失问题 decimal 关键字表示 128 位数据类型。 同浮点型相比&#xff0c;decimal 类型具有更高的精度和更小的范围&#xff0c;这使它适合于财务和货币计算 dou…

【MATLAB源码-第146期】基于matlab的信源编码仿真GUI,对比霍夫曼编码,算术编码和LZ编码。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 霍夫曼编码、算术编码和LZ编码是三种广泛应用于数据压缩领域的编码技术。它们各自拥有独特的设计哲学、实现方式和适用场景&#xff0c;因此在压缩效率、编解码速度和内存使用等方面表现出不同的特点。接下来详细描述这三种编…

【大厂AI课学习笔记】【2.2机器学习开发任务实例】(7)特征构造

特征分析之后&#xff0c;就是特征构造。 特征构造第一步 特征构造往往要进行数据的归一化。 在本案例中&#xff0c;我们将所有的数据&#xff0c;将所有特征区间调整为0~1之间。 如上图。 那么&#xff0c;为什么要进行归一化&#xff0c;又如何将数据&#xff0c;调整为…

信号处理与 signal.h 库

C 语言中的 signal.h 头文件提供了一种处理程序执行期间报告的不同信号的机制。它定义了一些变量类型、宏和函数&#xff0c;让程序能够更灵活地响应来自操作系统或其他进程的信号。 sig_atomic_t 类型 sig_atomic_t 类型是一种在信号处理程序中使用的整数类型。它保证在信号…

QtCreator“设计”按钮灰色无法点击,如何解决

Mac中安装QML Designer插件&#xff1a; 首选项-> 关于插件 -> 勾选QT Quick下的QML Designer 点击确定安装插件&#xff0c;重启Qt Creator后生效