日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > vue >内容正文

vue

threejs 导入gltf模型并添加Sprite标注,在vue结合websocket实时更新贴图的信息

發布時間:2024/1/1 vue 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 threejs 导入gltf模型并添加Sprite标注,在vue结合websocket实时更新贴图的信息 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

效果展示:

1. 導入依賴

import * as THREE from 'three'import {GLTFLoader} from 'three/examples/jsm/loaders/GLTFLoader';import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls'; //props: { // websockData: Object, //父組件傳遞的websocketData //}, data() {return {camera: null, //相機scene: null, //場景renderer: null, //渲染器container: null, //容器controls: null, //控制器sprites : [], //精靈、幾何體、材質、貼圖的集合,控制實時變化} },

2.創建相機、場景、光源、渲染器、控制器

//創建相機 initCamera() {this.camera = new THREE.PerspectiveCamera(45, this.container.clientWidth / this.container.clientHeight, 0.1, 10000)this.camera.position.set(43, 11, 22); //相機位置 }, //創建場景 initScene() {this.scene = new THREE.Scene()this.scene.background = new THREE.Color("#c5ccec");this.scene.add(this.camera) }, //光源 initLight() {//平行光,沿著特定方向發射的光const directionalLight1 = new THREE.DirectionalLight("#ccc", 1);directionalLight1.position.set(1, 1, 1);this.scene.add(directionalLight1);const directionalLight2 = new THREE.DirectionalLight("#ccc", 1);directionalLight2.position.set(-1, 0.5, -1);this.scene.add(directionalLight2);const directionalLight3 = new THREE.DirectionalLight("#ccc", 1);directionalLight3.position.set(-23, 1, 27);this.scene.add(directionalLight3);const directionalLight4 = new THREE.DirectionalLight("#ccc", 1);directionalLight4.position.set(24, 1, -24);this.scene.add(directionalLight4); }, //渲染器 initRenderer() {this.container = document.getElementById('container')this.renderer = new THREE.WebGLRenderer({antialias: true, alpha: true});this.renderer.setPixelRatio(this.container.devicePixelRatio);this.renderer.setSize(this.container.clientWidth, this.container.clientHeight);this.container.appendChild(this.renderer.domElement) }, //視圖控制器 initControls() {this.controls = new OrbitControls(this.camera, this.renderer.domElement);//上下翻轉的最大角度this.controls.maxPolarAngle = 1.5;//上下翻轉的最小角度this.controls.minPolarAngle = 0.3;//是否允許縮放this.controls.enableZoom = true;//控制是否帶有慣性this.controls.enableDamping = true },

3.導入GLTF模型

//加載設備模型 initGLTF(item) {let that = thisfunction onProgress(xhr) {if (xhr.lengthComputable) {const percentComplete = xhr.loaded / xhr.total * 100;// ${Math.round(percentComplete, 2)}% //加載進度}}function onError() {}//導入模型new GLTFLoader().setPath('static/obj/').load(item + '.gltf', function (object) {object.scene.position.x = 0;object.scene.position.z = 0;object.scene.name = item; //模型名稱object.scene.scale.set(0.1, 0.1, 0.1) //設置模型比例尺寸object.scene.traverse(function (child) {if (child.isMesh) {//給模型下的Mesh添加材質顏色child.material = new THREE.MeshPhongMaterial({color: child.material.color,shininess: 100,reflectivity: 0.5,flatShading: false})}});//給模型內的Mesh集合加到全局that.sprites = []object.scene.children.forEach(child => {that.sprites.push({mesh: child,sprite: null,texture: null,spriteMaterial: null,})});that.scene.add(object.scene);}, onProgress, onError); }

4.在animate中實時顯示Sprite

animate() {this.renderer.render(this.scene, this.camera);this.animateId = requestAnimationFrame(this.animate);//先清空精靈this.scene.children.forEach(child =>{if(child.type === "Sprite"){this.scene.remove(child);}})this.sprites.forEach(item => {if (item.sprite) { //注意加載前要把加載過的精靈銷毀掉,釋放內存this.scene.remove(item.sprite)this.scene.remove(item.texture)this.scene.remove(item.spriteMaterial)}//繪制矩形var canvas = document.createElement("canvas");var context = canvas.getContext("2d");//canvas 實體context.fillStyle = "rgba(0,0,0,0.5)"; //填充帶透明顏色context.fillRect(0,0,600,200); //x,y,width,height//canvas 邊框context.lineJoin = "round";context.lineCap = 'round';context.miterLimit = 0;context.lineWidth = 5; //borderWidthcontext.strokeStyle = "#17fe6d";context.strokeRect(0,0,300,150);//canvas 文字context.fillStyle = "#fff";context.font = "24px bold Arial";context.fillText(item.mesh.name, 30, 30);context.fillStyle = "#fff";context.font = "20px bold Arial";context.fillText("websocket值:" + this.websockData['socketKey'], 30, 60);item.texture = new THREE.Texture(canvas); //就是上面的canvas,將它寫在一個函數中然后返回。item.texture.needsUpdate = true;item.spriteMaterial = new THREE.SpriteMaterial({map: item.texture});item.sprite = new THREE.Sprite(item.spriteMaterial);item.sprite.scale.set(2.5, 2.5, 2.5); //大小縮放item.sprite.position.set(item.mesh.position.x / 10, (item.mesh.position.y + 40) / 10 + 4, item.mesh.position.z / 10); //位置item.sprite.name = "標識圖"this.scene.add(item.sprite); //將其放入場景中}) },

5.獲取websocket數據

initWebSocket() {//初始化weosocket// this.websock = new WebSocket('ws://' + location.host + '/socket');this.websock = new WebSocket("ws://192.168.2.9:5002/socket");this.websock.onmessage = this.websocketonmessage;this.websock.onopen = this.websocketonopen;this.websock.onerror = this.websocketonerror;this.websock.onclose = this.websocketclose; }, websocketonmessage(e) {this.websockVarData = JSON.parse(e.data); }, websocketonopen() {console.log("socket連接成功") }, websocketonerror(){console.log("連接錯誤") }, websocketsend(Data) {this.websock.send(Data); }, websocketclose(e) {console.log("websocket關閉"); }, closesocket() {this.websock.close(); },

也可以在父組件調用,傳遞websockVarData值當前組件獲取,數據也是實時的,不需要用watch監聽值,在animate方法中是自動更新的

6.最后初始化方法

init() {this.initRenderer()this.initCamera()this.initScene()this.initLight()this.initGLTF("xx模型")this.initControls() }, mounted() {this.initWebSocket()this.init()this.animate() },

總結

以上是生活随笔為你收集整理的threejs 导入gltf模型并添加Sprite标注,在vue结合websocket实时更新贴图的信息的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。