一、最终效果图
二、遇到的问题解决办法
1.资源加载不出
a.TypeError: Cannot read properties of null (reading '1')
at parseHeader (PCDLoader.js?edd4:119:1)
at PCDLoader.parse (PCDLoader.js?edd4:226:1)
at Object.eval [as onLoad] (PCDLoader.js?edd4:34:1)
at XMLHttpRequest.eval (three.module.js?5a89:34770:1)
b.GET http://localhost:8080/public/Zaghetto 404 (Not Found)
两者本质同个问题,都是没有获取到pcd文件资源,第一个由于设置了vue-router,使他没有获取到后返回来index.html (官方文档https://router.vuejs.org/zh/guide/essentials/history-mode.html#html5-%E6%A8%A1%E5%BC%8F)
404,我先检查了路径名称发现没拼写错误,后来尝试 public下其他常见类型文件可以,只有这个pcd文件不行,然后我就看了他们的请求网站,发现pcd文件的请求网址多了个‘/public',导致请求路径错误。
解决办法:
url直接不写public/直接从第二级开始写
2.bufferGeometry报错
three.module.js?5a89:10091 THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The "position" attribute is likely to have NaN values.
字面意思是 'radius'和'position'现在值为非数字
从threejs源码中找到 computeBoundingSphere(),通过断点,可以看出是由于这个maxRadiusSq值为NaN,然后这个值又是由于center.distanceToSquared(_vector$8)为NaN, 导致Math.max为NaN。这个值是由于 _vector$8.fromBufferAttribute(position, i)为NaN,顺藤摸瓜发现最终是因为position里有的值为NaN,position从哪里来?是导入的pcd文件。
解决办法:
a. Math.max(a,b)a,b中有一个NaN就返回NaN,所以可以将threejs源码中Math.max()替换成其它比大小方法文章来源:https://www.toymoban.com/news/detail-479758.html
//maxRadiusSq = Math.max(maxRadiusSq, center.distanceToSquared(_vector$8));
//替换成
maxRadiusSq = center.distanceToSquared(_vector$8) > maxRadiusSq ? center.distanceToSquared(_vector$8) : maxRadiusSq
b.pcd文件不要含NaN文章来源地址https://www.toymoban.com/news/detail-479758.html
三、最终代码
<template>
<div
v-loading="loading"
element-loading-background="rgba(0, 0, 0, 0.8)"
id="pcdcontainer"
ref="pcdcontainer"
></div>
<!-- v-loding 是element Ui的 -->
</template>
<script>
import * as THREE from "three";
import { PCDLoader } from "three/examples/jsm/loaders/PCDLoader.js";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
export default {
created () {
},
data () {
return {
elem: null,
scene: null,
camera: null,
renderer: null,
loader: null,
controls: null,
clock: new THREE.Clock(),
loading: true,
pointcloud: null,
}
},
beforeMount () {
},
mounted () {
this.init()
},
methods: {
init () {
this.elem = document.getElementById('pcdContainer');//获取要渲染的Dom
// 相机
this.camera = new THREE.PerspectiveCamera(
30, // 视野
this.elem.clientWidth / this.elem.clientHeight, // 纵横比
0.1, // 近平面
1000 // 远平面
);
// 渲染器
this.renderer = new THREE.WebGLRenderer({
antialias: true,
alpha: true
});
this.renderer.setClearColor(new THREE.Color(0x303030)); // 背景色
this.renderer.setSize(this.elem.clientWidth, this.elem.clientHeight);
this.elem.appendChild(this.renderer.domElement);
this.scene = new THREE.Scene(); // 场景
this.loader = new PCDLoader(); //PCD加载器
const THIS = this
//加载PCD文件
THIS.loader.load(
'Zaghetto.pcd',
function (points) {
points.geometry.rotateX(0.5 * Math.PI);//旋转模型,可调
points.material.color = new THREE.Color(0x00ffff); // 模型颜色
THIS.scene.add(points);
var middle = new THREE.Vector3();
console.log(points.geometry);
points.geometry.computeBoundingBox();
points.geometry.boundingBox.getCenter(middle);
points.applyMatrix4(
new THREE.Matrix4().makeTranslation(
-middle.x,
-middle.y,
-middle.z
)
);
// 比例
var largestDimension = Math.max(
points.geometry.boundingBox.max.x,
points.geometry.boundingBox.max.y,
points.geometry.boundingBox.max.z
);
THIS.camera.position.y = largestDimension * 3;//相机位置,可调
THIS.animate();
//轨道控制器 旋转、平移、缩放
THIS.controls = new OrbitControls(
THIS.camera,
THIS.renderer.domElement
);
THIS.controls.enableDamping = true;//旋转、平移开启阻尼
THIS.controls.addEventListener("change", THIS.render); // 监听鼠标、键盘事件
放大缩小等
},
function (xhr) {
let load = xhr.loaded / xhr.total
if (load == 1) {
THIS.loading = false
}
},
function (error) {
console.log(error);
}
);
},
render () {
this.renderer.render(this.scene, this.camera);
},
animate () {
let delta = this.clock.getDelta();
if (this.controls) {
this.controls.update(delta);
}
requestAnimationFrame(this.animate)
this.render();
},
},
computed: {},
watch: {},
filters: {},
components: {}
}
</script>
<style scoped lang='scss'>
#pcdcontainer {
width: 1920px;
height: 1080px;
}
</style>
到了这里,关于【Three.js】vue2导入pcd文件 PCDLoader的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!