1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > threejs 导入gltf模型并添加Sprite标注 在vue结合websocket实时更新贴图的信息

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

时间:2019-01-25 23:25:27

相关推荐

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()},

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。