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

news2024/9/21 12:45:16

   使用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); //array
  if (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.coloradmin.cn/o/1464721.html

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

相关文章

【Linux】 login命令使用

login命令 在 Linux 中用于创建一个新的会话&#xff0c;并在新会话中登录用户。这个命令通常在终端中自动执行&#xff0c;当你打开一个新的终端会话或者通过 SSH 远程连接到 Linux 服务器时。 在命令后面附加欲登入的用户名称&#xff0c;它会直接询问密码&#xff0c;等待…

软件压力测试:测试方法与步骤详解

随着软件应用的不断发展&#xff0c;用户对系统性能的要求也逐渐提高。在不同的负载条件下&#xff0c;系统必须能够保持稳定、高效的运行。软件压力测试是一种验证系统在各种负载情况下性能表现的关键手段。本文将详细探讨软件压力测试的方法和步骤。 1. 明确测试目标 在进行压…

canvas水波纹效果,jquery鼠标水波纹插件

canvas水波纹效果&#xff0c;jquery鼠标水波纹插件 效果展示 jQuery水波纹效果&#xff0c;canvas水波纹插件 HTML代码片段 <div class"scroll04wrap"><h3>发展历程</h3><div class"scroll04"><p>不要回头&#xff0c;一…

Sora背后的论文(1):使用 lstms 对视频展现进行无监督学习

之前那篇《Sora背后的32篇论文》发出后&#xff0c;大家都觉得不错&#xff0c;有很多小伙伴都开始啃论文了。 那么我就趁热打铁&#xff0c;把这32篇论文的通俗解读版贴一下。 从去年开始&#xff0c;我基本上形成了一个思维方式&#xff0c;任何事情做之前先看看 有没有好的…

C++力扣题目 647--回文子串 516--最长回文子序列

647. 回文子串 力扣题目链接(opens new window) 给定一个字符串&#xff0c;你的任务是计算这个字符串中有多少个回文子串。 具有不同开始位置或结束位置的子串&#xff0c;即使是由相同的字符组成&#xff0c;也会被视作不同的子串。 示例 1&#xff1a; 输入&#xff1a…

C++ 文件操作-文本文件-读取和打开文件方法详解

读文件步骤 #include <iostream> using namespace std; #include <fstream> #include <string> //文本文件 读文件void test(){// 1 包含头文件// 2 创建流对象ifstream ifs;// 3 打开文件 并且判断是否打开成功ifs.open("table.txt",ios::in); //…

力扣随笔之两数之和 Ⅱ -输入有序数组(中等167)

思路&#xff1a;在递增数组中找出满足相加之和等于目标数 定义左右两个指针&#xff08;下标&#xff09;从数组两边开始遍历&#xff0c;若左右指针所指数字之和大于目标数&#xff0c;则将右指针自减&#xff0c;若左右指针所指数字之和小于目标数&#xff0c;则左指针自加&…

C# CAD2016 cass10宗地Xdata数据写入

一、 查看cass10写入信息 C# Cad2016二次开发获取XData信息&#xff08;二&#xff09; 一共有81条数据 XData value: QHDM XData value: 121321 XData value: SOUTH XData value: 300000 XData value: 141121JC10720 XData value: 权利人 XData value: 0702 XData value: YB…

VSCode-更改系统默认路径

修改vscode中的默认扩展路径&#xff1a;"%USERPROFILE%\.vscode" 打开目录C:\用户\电脑用户名&#xff0c;将.vscode文件剪切至D:\VSCode文件夹下 用管理员身份打开cmd.exe命令界面输入mklink /D "%USERPROFILE%\.vscode" "D:\VSCode\.vscode\"…

AI工具新革命:从ChatGPT到Sora,生成式AI改变世界

这个春节着实精彩&#xff0c;“春山学”吃透了&#xff0c;不如把目光移向OpenAI又一重磅产品——文生视频大模型Sora。智能新纪元已然开启&#xff0c;因为正如周鸿祎所说&#xff1a;“,Sora的诞生意味着AGI&#xff08;通用人工智能&#xff09;的实现将从10年缩短到1年。”…

【高德地图】Android高德地图初始化定位并显示小蓝点

&#x1f4d6;第3章 初始化定位并显示小蓝点 ✅第1步&#xff1a;配置AndroidManifest.xml✅第2步&#xff1a;设置定位蓝点✅第3步&#xff1a;初始化定位✅完整代码 ✅第1步&#xff1a;配置AndroidManifest.xml 在application标签下声明Service组件 <service android:n…

阿里开源低代码引擎 - Low-Code Engine

阿里开源低代码引擎 - Low-Code Engine 本文主要介绍如何在Windows运行/开发阿里开源低代码引擎 - Low-Code Engine 详细文档参见【 阿里开源低代码引擎 - Low-Code Engine 官方文档】 目录 阿里开源低代码引擎 - Low-Code Engine一、环境准备1、使用 WSL 在 Windows 上安装 L…

【Kotlin】流程控制

1 选择结构 Kotlin 中选择结构主要包含 if -else、when 语句&#xff0c;并且可以返回结果。 1.1 if-else 1.1. 条件选择 fun main() {var score 85if (score > 90) {println("优秀")} else if (score > 80) {println("良好")} else if (score &…

基于SSH打通隧道实现异地组网

前言 最近有异地组网的需求&#xff0c;我目前的是用蒲公英X1盒子来进行组网&#xff0c;但是蒲公英X1非会员账号有设备限制3个&#xff08;这个是硬伤&#xff09;&#xff0c;虽然说可以打通P2P但是在复杂的网络环境下概率不是特别高 所以研究下SSH异地组网的方式&#xff…

k8s(3)

目录 一.K8S的三种网络 flannel的三种模式: 在 node01 节点上操作&#xff1a; calico的 三种模式&#xff1a; flannel 与 calico 的区别&#xff1f; 二.CoreDNS 在所有 node 节点上操作&#xff1a; 在 master01 节点上操作&#xff1a; ​编辑 DNS 解析测试&#…

AIoT网关 人工智能物联网网关

AIoT(人工智能物联网)作为新一代技术的代表&#xff0c;正以前所未有的速度改变着我们的生活方式。在这个智能时代&#xff0c;AIoT网关的重要性日益凸显。它不仅是连接智能设备和应用的关键&#xff0c;同时也是实现智能化家居、智慧城市和工业自动化的必备技术。      一…

OCPP 1.6 接入实现文档

一、简介 OCPP&#xff08;Open Charge Point Protocol&#xff09;是一个开放的通信协议&#xff0c;用于充电站&#xff08;Charge Point&#xff09;与中央系统&#xff08;Central System&#xff0c;如充电站管理系统或服务提供商平台&#xff09;之间的通讯。本篇文档将…

【嵌入式实践】【复刻篇】从0到1给电动车添加指纹锁

0. 成果展示 视频地址&#xff1a;b站链接 软件、硬件、机械原件存放位置&#xff1a;https://gitee.com/sunkai64/zhima 1. 机械设计篇 存放位置&#xff1a;/zhima/03.machineDesign。我上传了2种格式的文件&#xff0c;SLDPRT格式的文件可以使用solidworks软件打开后进行编…

OpenCV中图像的HSV色彩空间

在HSV 色彩空间中H, S, V 这三个通道分别代表着色相(Hue)&#xff0c;饱和度(Saturation)和明度(Value)&#xff0c; 原本输出的HSV 的取值范围分别是0-360, 0-1, 0-1; 但是为了匹配目标数据类型OpenCV 将每个通道的取值范围都做了修改,于是就变成了0-180, 0-255, 0-255 impo…

【Linux从青铜到王者】 基础IO

本篇重点&#xff1a;文件描述符&#xff0c;重定向&#xff0c;缓冲区&#xff0c;磁盘结构&#xff0c;文件系统&#xff0c;inode理解文件的增删查改&#xff0c;查找一个文件为什么一定要有路径&#xff0c;动静态库&#xff0c;有的时候为什么找不到库&#xff0c;动态库的…