700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > Webgl(ThreeJS)在移动端实现室内漫游的解决方案(附工程)

Webgl(ThreeJS)在移动端实现室内漫游的解决方案(附工程)

时间:2021-08-27 03:35:53

相关推荐

Webgl(ThreeJS)在移动端实现室内漫游的解决方案(附工程)

在移动端实现室内漫游,先看效果截图:

整体的漫游Demo效果看链接:

技术点:

一、加载模型

采用异步加载glb模型。

function loadModel(name) {var modelName = name + '.glb';// modelvar model = null;new GLTFLoader().setPath('glb/hp/').load(modelName, function (gltf) {scene.add(gltf.scene);model = gltf.scene;//model.position.x = index * 0.5;console.log(model.position.x);model.scale.x = 0.1;model.scale.y = 0.1;model.scale.z = 0.1;// console.log(gltf);console.log(model);//获取一个模型的世界坐标之前,需要执行 更新模型的世界矩阵//scene.updateMatrixWorld(true);//model.updateMatrixWorld();// 声明一个三维向量用来保存网格模型的世界坐标//var worldPosition = new THREE.Vector3();// 获得世界坐标,执行getWorldPosition方法,提取网格模型的世界坐标结果保存到参数worldPosition中//model.getWorldPosition(worldPosition)//console.log(worldPosition);//console.log("00000000000000000000000000000000000000000000000000");if (name == 'SM_daohang') { //if (model.name == 'SM_daohang') {daohangModel = model;daohangModel.visible = false;}loadIndex++;if (loadIndex < modelList.length) {updateProgressBar(loadIndex / modelList.length);loadModel(modelList[loadIndex]);} else {hideProgressBar();////hideProgressBar();// model.children.forEach(mo => {// console.log(mo.name);// if (mo.name == 'SM_fangti_01') {// //console.log("22222");// //parentObj = mo;// //mo.visible = false;// } else if (mo.name.indexOf('shujia') > -1) {// }// });readTxt();}});}

二、空间中路线规划

通过在场景中打点记录下要漫游的路线,打点的方法如下:

function onMouseDBClick(event) {console.log(camera);mouse.x = (event.clientX / window.innerWidth) * 2 - 1;mouse.y = - (event.clientY / window.innerHeight) * 2 + 1;// 通过鼠标点的位置和当前相机的矩阵计算出raycasterraycaster.setFromCamera(mouse, camera);// 获取raycaster直线和所有模型相交的数组集合var intersects = raycaster.intersectObjects(scene.children);// console.log(intersects);if (intersects.length > 0) {//SM_fangti_01//if (intersects[0].object.name == 'SM_fangti_01') {var index = 0;//console.log(intersects[0].object.parent);//intersects[0].object.material.color.set(0xff0000);var x = intersects[index].point.x;var y = intersects[index].point.y;var z = intersects[index].point.z;//z += 1;//向上抬高//endPosition = new THREE.Vector3(x, y, z);;console.log(x, y, z);pointsList.push(x);pointsList.push(y);pointsList.push(z);//画点positions = [];positions.push(x, y, z);const geometry2 = new THREE.BufferGeometry();const colors2 = [];colors2.push(1, 0, 0);geometry2.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3));geometry2.setAttribute('color', new THREE.Float32BufferAttribute(colors2, 3));puteBoundingSphere();const material2 = new THREE.PointsMaterial({ size: 0.1, vertexColors: true });// if (myPoints2) {// scene.remove(myPoints2);// myPoints2 = null;// }var myPoints2 = new THREE.Points(geometry2, material2);scene.add(myPoints2);//}}}

三、3D场景中画线

画线:通过line2来实现线条的粗细设置

function drawLine2(pointArr) {// Line2 ( LineGeometry, LineMaterial )let geometry2 = new LineGeometry();//var pointArr = [this.model.start.x, this.model.start.y, this.model.start.z, this.model.end.x, this.model.end.y, this.model.end.z]geometry2.setPositions(pointArr);let material2 = new LineMaterial({linewidth: 0.001,color: 'blue',dashOffset: 15,dashScale: 10,dashSize: 10,gapSize: 20});material2.resolution.set(window.innerWidth + 100, window.innerHeight + 100);//这句如果不加宽度仍然无效line2 = new Line2(geometry2, material2);line2.name = "lines";scene.add(line2);line2.visible = getBookID();}function readTxt() {positions = [];var arr = testPoints.split(',');for (var i = 0; i < arr.length; i++) {positions.push(arr[i]);}//drawLineDashed(positions);drawLine2(positions);}

四、自动漫游

采用twenn.js做的漫游动画,只是简单的漫游,很多细节没有做优化

var tween;var pathIndex = 0;function cameraRunPath(time) {isRun = true;bookClick = false;var runPosition = runPath[pathIndex];tween = new TWEEN.Tween(camera.position).to({ x: runPosition.x, y: runPosition.y, z: runPosition.z }, time) // 目标位置与时间.delay(0) // 延迟时间.easing(TWEEN.Easing.Exponential.Out).onUpdate(function () {//运动过程//controls.moveForward(0.01 * speed);//console.log("22222", camera.position);//camera.position.set(runPosition.x, runPosition.y, runPosition.z);camera.lookAt(runPosition.x, runPosition.y, runPosition.z);}).onComplete(() => {//console.log("99999", camera.position);pathIndex++;if (pathIndex < runPath.length) {var time = pathIndex == 1 ? 4000 : 3000;cameraRunPath(time);} else {camera.rotation.set(-3.08, 0.0455, 3.1388);bookClick = true;isRun = false;}});tween.easing(TWEEN.Easing.Quadratic.InOut);tween.start();}

五、移动端点击事件的响应。

//点击事件document.getElementById("nvImg").onclick = function () { resetButtonEvent(); };document.getElementById("lineImg").onclick = function () { lineButtonEvent(); };document.getElementById("testbook").onclick = function () { bookButtonEvent(); };//window.innerWidth / window.innerHeight//document.getElementById("testbook").style.left = ;//第一个div的left值//document.getElementById("testbook").style.top = window.innerHeight / 2 + "px";//第一个div的top值document.getElementById("testbook").style.display = "none";// document.getElementById("playDiv").onclick = function () { playButtonEvent(); };// document.getElementById("take_partDiv").onclick = function () { take_partButtonEvent(); };// document.getElementById("detailDiv").onclick = function () { detailButtonEvent(); };// document.getElementById("fireDiv").onclick = function () { fireButtonEvent(); };// document.getElementById("hideDiv").onclick = function () { hideButtonEvent(); };if (isPhone()) {window.addEventListener('touchstart', onMouseClick, false);// window.addEventListener('touchstart', onMouseDown, false);// window.addEventListener('touchend', onMouseUp, false);window.addEventListener('touchmove', onMouseMove, false);} else {//dblclick//window.addEventListener('dblclick', onMouseDBClick, false);window.addEventListener('click', onMouseClick, false);// window.addEventListener('mousedown', onMouseDown, false);// window.addEventListener('mouseup', onMouseUp, false);window.addEventListener('mousemove', onMouseMove, false);}

六、最后整体的工程文件供学习

webgl(threejs)实现室内漫游-导航功能-应用于移动端-Javascript文档类资源-CSDN下载

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