vue+threeJs 根据屏幕调整gltf模型的大小、重心、并更换骑车整体颜色

        嗨,我是小路。今天主要和大家分享的主题是“vue+threeJs 根据屏幕调整gltf模型的大小、重心、并更换骑车整体颜色”。        

项目案例示意图

1.整体更换gltf模型的颜色

定义:整体代码如下。颜色是事先设定的

const colorAry = reactive(["rgb(216, 27, 67)", "rgb(142, 36, 170)", "rgb(81, 45, 168)", "rgb(48, 63, 159)", "rgb(30, 136, 229)", "rgb(0, 137, 123)","rgb(67, 160, 71)", "rgb(251, 192, 45)", "rgb(245, 124, 0)", "rgb(230, 74, 25)", "rgb(233, 30, 78)", "rgb(156, 39, 176)","rgb(0, 0, 0)"])
//设置车身颜色
const setCarColor = (index) => {const currentColor = new THREE.Color(colorAry[index]);scene.traverse(child => {if (child.isMesh) {console.log(child.name)if (child.name.includes('door_')) {child.material.color.set(currentColor)}}})
}

2.计算gltf模型大小,进行缩放

二、实例代码

<template><div class="pageBox"><div class="leftBox" ref="leftRef"></div><div class="rightBox" ref="rightRef" :style="{ background: bgColor }"><div @click="setCarColor(index)" v-for="(item,index) in colorAry":style="{backgroundColor : item}">{{item}}</div></div></div>
</template>
<script setup>
import { onMounted, reactive, ref } from 'vue';
import * as THREE from 'three';
// 引入轨道控制器扩展库OrbitControls.js
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
// 设置相机控件轨道控制器OrbitControls// 引入gltf模型加载库GLTFLoader.js
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
import { getRandomColor } from '../utils/commonThree';const bgColor = ref("")
//实例化一个gui对象
// const gui = new GUI();const leftRef = ref();
const rightRef = ref()
// 定义相机输出画布的尺寸(单位:像素px)
let width = 800; //宽度
let height = window.innerHeight; //高度
// 创建3D场景对象Scene
const scene = new THREE.Scene();
//设置背景色
scene.background = new THREE.Color("#ffffff");// 实例化一个透视投影相机对象
const camera = new THREE.PerspectiveCamera(50, width / height, 2, 6000);//=======================================================
const spotLight = new THREE.SpotLight(0xffffff, 1.0);const clock = new THREE.Clock();//===============================================
// 创建GLTF加载器对象
const loader = new GLTFLoader();// 创建渲染器对象
const renderer = new THREE.WebGLRenderer();const modelObj = reactive({ index: 1, url: './models/3d/tesla_2018_model_3/scene.gltf' });//车身颜色数组onMounted(() => {initData()render();//添加相机空间const controls = new OrbitControls(camera, renderer.domElement);controls.maxPolarAngle = 0.9 * Math.PI / 2controls.enableZoom = true// 如果OrbitControls改变了相机参数,重新调用渲染器渲染三维场景controls.addEventListener('change', function () {renderer.render(scene, camera); //执行渲染操作});//监听鼠标、键盘事件})
const initData = () => {//环境光:没有特定方向,整体改变场景的光照明暗const ambient = new THREE.AmbientLight(0xffffff, 0.4);scene.add(ambient);scene.add(spotLight);//光源添加到场景中// 根据需要设置相机位置具体值camera.position.set(200, 200, 200);//const gridHelper = new THREE.GridHelper(1000,50,getRandomColor(),getRandomColor());scene.add(gridHelper);loadGltfData();renderer.setSize(width, height); //设置three.js渲染区域的尺寸(像素px)//将innerHTML置空,避免append重复添加渲染leftRef.value.innerHTML = ''leftRef.value.append(renderer.domElement);
}let mixer = "";const colorAry = reactive(["rgb(216, 27, 67)", "rgb(142, 36, 170)", "rgb(81, 45, 168)", "rgb(48, 63, 159)", "rgb(30, 136, 229)", "rgb(0, 137, 123)","rgb(67, 160, 71)", "rgb(251, 192, 45)", "rgb(245, 124, 0)", "rgb(230, 74, 25)", "rgb(233, 30, 78)", "rgb(156, 39, 176)","rgb(0, 0, 0)"])
//设置车身颜色
const setCarColor = (index) => {const currentColor = new THREE.Color(colorAry[index]);scene.traverse(child => {if (child.isMesh) {console.log(child.name)if (child.name.includes('door_')) {child.material.color.set(currentColor)}}})
}
//加载gltf模型
const group = new THREE.Group();
const loadGltfData = () => {modelObj.url && loader.load(modelObj.url, function (gltf) {console.log(gltf)//加载完成//设置模型的位置// 计算几何体中心//获取模型的长、宽、高let scale = getScale(gltf.scene)//同比例放大,模型不变形gltf.scene.scale.set(scale,scale,scale);const box = new THREE.Box3().setFromObject(gltf.scene);const center = box.getCenter(new THREE.Vector3());// 将模型几何顶点平移到中心点位置gltf.scene.position.set(-center.x, -center.y, -center.z);gltf.scene.position.x = 10;group.add(gltf.scene);group.position.y = 50;scene.add(group);}, function (xhr) {//加载时console.log((xhr.loaded / xhr.total * 100) + '% loaded');}, function (error) {console.log('加载失败', error);})
}
//获取模型长宽高
const getScale = (model) => {// 计算模型的边界框const box = new THREE.Box3().setFromObject(model);// 获取边界框的尺寸const size = new THREE.Vector3();box.getSize(size);//以屏幕的一般高度为放缩比例let scale = (height / 2) / size.z;return scale;
}//渲染
const render = () => {//解决加载gltf格式模型纹理贴图和原图不一样问题renderer.outputEncoding = THREE.sRGBEncoding;mixer ? mixer.update(clock.getDelta()) : null;group.rotation.y += 0.01;renderer.render(scene, camera); //执行渲染操作//重复渲染requestAnimationFrame(render);//请求再次执行渲染函数render,渲染下一帧
}</script>
<style scoped lang="less">
.pageBox {width: 100%;height: 100vh;padding: 0;margin: 0;display: flex;justify-content: space-between;align-items: center;.rightBox {width: 100%;height: 100%;background: yellow;}
}
</style>

三、总结

       1、后面需要向更复杂的3D展厅进行调整。

        2、自动计算模型和模型的重心,并调整模型的大小,已经重心的位置。自适应屏幕调整。

        3、这些方法都很适合在实际项目中开发运用。

最后一句,自我勉励:宁可十年不将军,不可一日不拱卒!

都看到这里了,记得【点赞】+【关注】哟。

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

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

相关文章

03 基于 java udp 做一个dns服务器 和 一个dns代理服务器

前言 这个也是 来自于一个朋友的需求 最终的目的是实现一个 dns 代理服务器, 当然 这本质也是一个 dns 服务器 并且 dns 代理服务器是依赖于 一个 dns 服务器的, 因此 顺便给一个 dns 服务器的 demo 这里 主要是 基于 udp 的一个 dns 请求, 响应数据的交互 dns 服务器 …

【HITCSAPP 哈工大计算机系统期末大作业】 程序人生-Hello’s P2P

计算机系统 大作业 题 目 程序人生-Hello’s P2P 专 业 计算机与电子通信类 学   号 2023112915 班   级 23L0505 学 生 杨昕彦 指 导 教 师 刘宏伟 计算机科学…

第十周作业

一、CSRF 1、DVWA-High等级 2、使用Burp生成CSRF利用POC并实现攻击 二、SSRF&#xff1a;file_get_content实验&#xff0c;要求获取ssrf.php的源码 三、RCE 1、 ThinkPHP 2、 Weblogic 3、Shiro

PTA刷题笔记(难度预警!!!有详解)

7-18 二分法求多项式单根 代码如下&#xff1a; ​ #include <stdio.h> #include <math.h>// 定义多项式函数 double polynomial(double x, double a3, double a2, double a1, double a0) {return a3 * x * x * x a2 * x * x a1 * x a0; }// 二分法求根函数 do…

打破传统范式,线上 3D 画展彰显多元亮点

&#xff08;一&#xff09;沉浸式体验&#xff0c;身临其境赏画​ 线上 3D 画展运用先进的 3D 建模和虚拟现实&#xff08;VR&#xff09;技术&#xff0c;高度还原了真实的展厅环境 。展厅内的布局、灯光&#xff0c;甚至墙壁的质感都被完美复刻&#xff0c;让观众仿佛置身于…

Docker架构详解

一,Docker的四大要素&#xff1a;Dockerfile、镜像(image)、容器(container)、仓库(repository) 1.dockerfile&#xff1a;在dockerfile文件中写构建docker的命令,通过dockerbuild构建image 2.镜像&#xff1a;就是一个只读的模板&#xff0c;镜像可以用来创建docker容器&…

【工具类】常用的工具类——CollectionUtil

目录 cn.hutool.core.collection.CollectionUtil集合创建集合清空集合判空集合去重集合过滤集合转换集合合并集合交集集合差集集合是否包含元素集合是否包含指定元素&#xff08;自定义条件&#xff09;集合分页集合分组集合转字符串元素添加元素删除根据属性转Map获取元素获取…

从零起步搭建基于华为云构建碳排放设备管理系统的产品设计

目录 &#x1f33f; 华为云 IoT&#xff1a;轻松上手碳排放设备管理系统搭建 &#x1f30d; 逐步搭建搭建规划 &#x1f680; 一、系统蓝图&#xff1a;5大核心模块&#xff0c;循序渐进 1️⃣ 设备管理与数据采集层 2️⃣ 数据传输与协议转换层 3️⃣ 数据处理与分析层…

华为OD机试真题—— 小明减肥(2025B卷:100分)Java/python/JavaScript/C/C++/GO最佳实现

2025 B卷 100分 题型 本专栏内全部题目均提供Java、python、JavaScript、C、C++、GO六种语言的最佳实现方式; 并且每种语言均涵盖详细的问题分析、解题思路、代码实现、代码详解、3个测试用例以及综合分析; 本文收录于专栏:《2025华为OD真题目录+全流程解析+备考攻略+经验分…

数据结构 -- 插入排序(直接插入排序和希尔排序)

插入排序 算法思想 每次将⼀个待排序的记录按其关键字大小插入到前面已排好序的子序列中&#xff0c;直到全部记录插入完成。 代码实现 void InsertSort(int A[],int n){int i,j,temp;for(i 1;i<n;i){if(A[i]<A[i-1]){temp A[i]; //用temp暂存A[i]for(ji-1;j>…

word中表格拉不动以及插入图片有间距

word中的表格宽度和高度怎么调整都改不了&#xff0c;可以将选中表格—右键—段落—取消勾选下图中的两项。 word中表格插入图片始终有间隙&#xff0c;怎么也消除不了间隙&#xff0c;可以在表布局—单元格边距—修改上下左右边距为0即可

网络抓包命令tcpdump及分析工具wireshark使用

文章目录 环境文档用途详细信息 环境 系统平台&#xff1a;Linux x86-64 Red Hat Enterprise Linux 8,Linux x86-64 Red Hat Enterprise Linux 7,Linux x86-64 SLES 12,银河麒麟 &#xff08;鲲鹏&#xff09;,银河麒麟 &#xff08;X86_64&#xff09;,银河麒麟&#xff08;龙…

Eigen矩阵存储顺序以及转换

一、Eigen矩阵存储顺序 在矩阵运算和线性代数中,"行优先"(Row-major)和"列优先"(Column-major)是两种不同的存储方式,它们决定了多维数组(如矩阵)在内存中的布局顺序。 1. 行优先(Row-major) 定义:矩阵按行顺序存储在内存中,即第一行的所有元…

快速部起一个Openwhisk平台,使用telego k8s服务部署能力内网部署

Telego 简介与 OpenWhisk 部署实践 概述 Telego 是一个用于便携式 Kubernetes 部署的工具&#xff0c;旨在解决容器镜像拉取中的网络代理问题。本文档描述了如何通过 Telego 将 Apache OpenWhisk&#xff08;一个 Serverless 计算平台&#xff09;部署到 Kubernetes 集群&…

LockSupport与Condition解析

本章我们介绍两个Java 并发包中用于线程协作的工具--LockSupport和Condition LockSupport&#xff1a; Java 并发包&#xff08;java.util.concurrent.locks&#xff09;提供了基于许可&#xff08;permit&#xff09;的线程阻塞和唤醒机制--LockSupport 对于LockSupport是通…

【机器学习基础】机器学习入门核心算法:逻辑回归(Decision Tree)

机器学习入门核心算法&#xff1a;逻辑回归&#xff08;Decision Tree&#xff09; 一、算法逻辑1.1 基本概念1.2 算法流程 二、算法原理与数学推导2.1 特征选择指标信息熵&#xff08;ID3算法&#xff09;信息增益&#xff08;Information Gain&#xff09;信息增益率&#xf…

网络编程3

管道的性质 读缓冲区为空&#xff0c;read阻塞写缓冲区为空&#xff0c;write阻塞一端先close&#xff0c;另一端继续read&#xff0c;read不阻塞&#xff0c;立刻返回0一端先close&#xff0c;另一端继续write&#xff0c;write会触发SIGPIPE信号&#xff0c;进程异常终止 soc…

influxdb时序数据库

以下概念及操作均来自influxdb2 官方文档 InfluxDB2 is the platform purpose-built to collect, store, process and visualize time series data. Time series data is a sequence of data points indexed in time order. Data points typically consist of successive meas…

洛谷 P3372 【模板】线段树 1

【题目链接】 洛谷 P3372 【模板】线段树 1 【题目考点】 1. 线段树 2. 树状数组 【解题思路】 本题要求维护区间和&#xff0c;实现区间修改、区间查询。 可以使用树状数组或线段树完成该问题&#xff0c;本文仅介绍使用线段树的解法。 解法1&#xff1a;线段树 线段树…

软件更新 | TSMaster 202504 版本已上线!三大功能让车载测试更智能

车载测试的智能化时代正在加速到来&#xff01;TSMaster 202504 版本正式发布&#xff0c;本次更新聚焦以太网通信与数据高效处理&#xff0c;带来三大核心功能升级—以太网报文信息过滤、XCP on Ethernet支持、按时间范围离线回放&#xff0c;助力工程师更精准、更灵活地完成测…